Skip to content

Releases: JoshuaSledden/Jigson

0.1.3

17 Sep 18:23
Compare
Choose a tag to compare

Jigson Library Update - Patch Notes 0.1.3

Improvements to the mapping profile configuration

I personally found the original mapping to appear too verbose and hard to read and maintain.

I wanted to reduce visual complexity while retaning the granularity and customization of the mapping:

Changes

  • Template-based Mapping: Added a new add_mapping function that supports template-based mapping for more flexible and type-safe property mapping.

  • Chained Function Mapping: Enabled the ability to chain multiple add_mapping calls for more concise and readable mapping definitions.

  • Optional Converter Function: Introduced an optional converter function parameter in the new add_mapping function, allowing for advanced or conditional mapping scenarios.

  • Improved Type Handling: Enhanced type checking and handling, including support for directly mappable types and complex types.

  • Error Handling: Added runtime error throwing for invalid mapping scenarios, improving debugging and error detection.

Code Implementation Examples

Template-based Mapping with Chaining

template<>
void mapping::MapperFactory::configure_profile<Person>(mapping::MappingProfile<Person> &profile) {
    profile
        .add_mapping("name", &Person::name)
        .add_mapping("age", &Person::age);
}

Using Optional Converter Function

template<>
void mapping::MapperFactory::configure_profile<Person>(mapping::MappingProfile<Person> &profile) {
    profile
        .add_mapping("name", &Person::name)
        .add_mapping("age", &Person::age, [](Person &p, const json_payload &j) {
              const auto age = j.get<int>();
              p.age = age;
              p.is_adult = age >= 18;
        });
}

Nested Mapping Profiles

template <>
inline void mapping::MapperFactory::configure_profile<Address>(mapping::MappingProfile<Address>& profile) {
  profile
      .add_mapping("street", &Address::street)
      .add_mapping("city", &Address::city);
}

template<>
void mapping::MapperFactory::configure_profile<Person>(mapping::MappingProfile<Person> &profile) {
    profile
        .add_mapping("name", &Person::name)
        .add_mapping("age", &Person::age)
        .add_mapping("address", &Person::address, [](Person &p, const json_payload &j) {
                p.address = mapping::get_mapper().map<Address>(j);
            });
}

Error handling

The new add_mapping function uses a concept to constrain the type of the mapping to simple types such as arithmetics and strings (and lists of such). Any more complicated mapping types should use the converter function parameter.

Any invalid types will be error handled:

template<typename PropertyType>
auto &add_mapping(const std::string &json_key, PropertyType T::*member_ptr, MappingFunction converter = nullptr) {
    // ... (other code)
    if constexpr (DirectlyMappableType<PropertyType>) {
        obj.*member_ptr = j.get<PropertyType>();
    } else {
        throw std::runtime_error("Invalid mapping provided for property " + json_key);
    }
    // ... (other code)
}

0.1.2

11 Sep 15:43
Compare
Choose a tag to compare
initial commit