smotastic / smartstruct

Dart Code Generator for generating mapper classes
35 stars 20 forks source link

Add some function #57

Closed skykaka closed 2 years ago

skykaka commented 2 years ago
  1. Retain the more information about source filed by "RefChain.dart"; When I use "object-box" and "smartstruct" at one time, I have some trouble.
    
    class Source {
    final one = ToOne<SubSource>() ;
    }

class Target { late SubTarget one; }

class SubSource { }

class SubTarget {

}

@Mapper() abstract class SourceMapper {

@Mapping(target: "one", source: "prop.one.target")
Target fromSource(Source source);

SubTarget fromSubSource(SubSource subSource);

}

The type of source "prop.code.target" is "SubSource" and the target "one" is "SubTarget", so it need the nested mapping "fromSubSource".
But the code doesn't know the type of "prop.one.target", because it is a generic type in "ToOne" class. In the "SourceAssignment", the only type info of "prop.one.target" is "EntityT" which is a type variable in the "ToOne" class. It's impossible that finding the correct nested mapping for the "prop.one.target".
The "RefChain" class can record the real type of "prop",“prop.one" and "prop.one.target". The "RefChain" also record the nullability of each of the property. 

2.  Apply nested mapping after function mapping. 
      Sometimes the result of function mapping need to mapped again by the nested mapping.
```dart
class Source {
  late SubSourceRef source;
}

class Target {
  late SubTarget target;
}

class SubSource {
}

class SubTarget {
}

class SubSourceRef {
     late SubSource source;
}

@Mapper()
abstract class ModelMapper {

  @Mapping(source: refToSource, target: 'source')
  Target fromSource(Source source);
  SubTarget fromSubSource(SubSource subSource);    

}

// The return value need to be mapped again by the nested mapping('fromSubSource').
SubSource refToSource(SubSourceRef ref) => ref.source;

And the generate code is

class ModelMapperImpl extends ModelMapper {
  ModelMapperImpl() : super();

  @override
  Target fromSource(Source source) {
    final target = Target();
    return target;
  }

  @override
  SubTarget fromSubSource(SubSource subSource) {
    final subtarget = SubTarget();
    return subtarget;
  }
}
  1. Ingore the nullability of type in nested mapping function matching. So the nested mapping function can be matched more easily.

  2. Pass on the mapper pointer to the function mapping method by the named parameters.

    
    @Mapper
    abstract ModelMapper {
    
    @Mapping(source=funMapping, target="data")
    Target fromSource(Source source);
    // ...
    }
    funMapping(Source source, {
    mapper: ModelMapper
    }) {

}

5. Extend the availability of the shouldAssignList. More list like object can be mapped automatically.

```dart
class Source {
    late Set<String> nameList;
}

class Target {
    late List<String> nameList;
}

The "Source.nameList" can be mapped to "Target.nameList" automatically.

  1. Add null check code in the generate code. When the input of "nestedMappingMethod" is not nullable and the input property is nullable, the 'null check code' will be generated. Just like:
    
    target = source == null ? null : nestedMappingMethod(source)
smotastic commented 2 years ago

Hi @skykaka Didn't forget you, but I'm in holiday right now so I don't have access to my regular tools. Will make sure to check your changes out as soon as I'm back

skykaka commented 2 years ago

Hi @smotastic Take your time. There's no hurry and enjoy your holiday.