lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

dto.rs (11874B)


      1 use dto_bindgen_core::{
      2     DescribeCtx, Dto, EnumDef, EnumRepr, FieldDef, FieldPresence, IdentName, RootDescriptor,
      3     RustTypeId, SourceSpan, StructDef, TargetFieldNames, TypeDef, TypeRef, VariantDef,
      4     VariantShape, WireFieldNames,
      5 };
      6 
      7 use crate::{
      8     RadrootsCoreCurrency, RadrootsCoreDecimal, RadrootsCoreDiscount, RadrootsCoreDiscountScope,
      9     RadrootsCoreDiscountThreshold, RadrootsCoreDiscountValue, RadrootsCoreMoney,
     10     RadrootsCorePercent, RadrootsCoreQuantity, RadrootsCoreQuantityPrice, RadrootsCoreUnit,
     11     RadrootsCoreUnitDimension,
     12 };
     13 
     14 pub fn dto_roots() -> [RootDescriptor; 10] {
     15     [
     16         RootDescriptor::new::<RadrootsCoreDiscount>(),
     17         RootDescriptor::new::<RadrootsCoreDiscountScope>(),
     18         RootDescriptor::new::<RadrootsCoreDiscountThreshold>(),
     19         RootDescriptor::new::<RadrootsCoreDiscountValue>(),
     20         RootDescriptor::new::<RadrootsCoreMoney>(),
     21         RootDescriptor::new::<RadrootsCorePercent>(),
     22         RootDescriptor::new::<RadrootsCoreQuantity>(),
     23         RootDescriptor::new::<RadrootsCoreQuantityPrice>(),
     24         RootDescriptor::new::<RadrootsCoreUnit>(),
     25         RootDescriptor::new::<RadrootsCoreUnitDimension>(),
     26     ]
     27 }
     28 
     29 impl Dto for RadrootsCoreCurrency {
     30     fn describe(_ctx: &mut DescribeCtx) -> TypeRef {
     31         TypeRef::String
     32     }
     33 }
     34 
     35 impl Dto for RadrootsCoreDecimal {
     36     fn describe(_ctx: &mut DescribeCtx) -> TypeRef {
     37         TypeRef::String
     38     }
     39 }
     40 
     41 impl Dto for RadrootsCoreUnitDimension {
     42     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
     43         let def = EnumDef::new(
     44             "RadrootsCoreUnitDimension",
     45             "RadrootsCoreUnitDimension",
     46             EnumRepr::External,
     47             span("crates/core/src/unit.rs", 17),
     48         )
     49         .with_variant(unit_variant(
     50             "Count",
     51             "count",
     52             "crates/core/src/unit.rs",
     53             18,
     54         ))
     55         .with_variant(unit_variant("Mass", "mass", "crates/core/src/unit.rs", 19))
     56         .with_variant(unit_variant(
     57             "Volume",
     58             "volume",
     59             "crates/core/src/unit.rs",
     60             20,
     61         ));
     62         register(ctx, "RadrootsCoreUnitDimension", TypeDef::Enum(def))
     63     }
     64 }
     65 
     66 impl Dto for RadrootsCoreUnit {
     67     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
     68         let def = EnumDef::new(
     69             "RadrootsCoreUnit",
     70             "RadrootsCoreUnit",
     71             EnumRepr::External,
     72             span("crates/core/src/unit.rs", 24),
     73         )
     74         .with_variant(unit_variant("Each", "each", "crates/core/src/unit.rs", 25))
     75         .with_variant(unit_variant("MassKg", "kg", "crates/core/src/unit.rs", 26))
     76         .with_variant(unit_variant("MassG", "g", "crates/core/src/unit.rs", 27))
     77         .with_variant(unit_variant("MassOz", "oz", "crates/core/src/unit.rs", 28))
     78         .with_variant(unit_variant("MassLb", "lb", "crates/core/src/unit.rs", 29))
     79         .with_variant(unit_variant("VolumeL", "l", "crates/core/src/unit.rs", 30))
     80         .with_variant(unit_variant(
     81             "VolumeMl",
     82             "ml",
     83             "crates/core/src/unit.rs",
     84             31,
     85         ));
     86         register(ctx, "RadrootsCoreUnit", TypeDef::Enum(def))
     87     }
     88 }
     89 
     90 impl Dto for RadrootsCoreMoney {
     91     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
     92         let def = StructDef::new(
     93             "RadrootsCoreMoney",
     94             "RadrootsCoreMoney",
     95             span("crates/core/src/money.rs", 8),
     96         )
     97         .with_field(field(
     98             "amount",
     99             "amount",
    100             RadrootsCoreDecimal::describe(ctx),
    101             "crates/core/src/money.rs",
    102             9,
    103         ))
    104         .with_field(field(
    105             "currency",
    106             "currency",
    107             RadrootsCoreCurrency::describe(ctx),
    108             "crates/core/src/money.rs",
    109             10,
    110         ));
    111         register(ctx, "RadrootsCoreMoney", TypeDef::Struct(def))
    112     }
    113 }
    114 
    115 impl Dto for RadrootsCorePercent {
    116     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    117         let def = StructDef::new(
    118             "RadrootsCorePercent",
    119             "RadrootsCorePercent",
    120             span("crates/core/src/percent.rs", 9),
    121         )
    122         .with_field(field(
    123             "value",
    124             "value",
    125             RadrootsCoreDecimal::describe(ctx),
    126             "crates/core/src/percent.rs",
    127             10,
    128         ));
    129         register(ctx, "RadrootsCorePercent", TypeDef::Struct(def))
    130     }
    131 }
    132 
    133 impl Dto for RadrootsCoreQuantity {
    134     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    135         let unit = RadrootsCoreUnit::describe(ctx);
    136         let def = StructDef::new(
    137             "RadrootsCoreQuantity",
    138             "RadrootsCoreQuantity",
    139             span("crates/core/src/quantity.rs", 13),
    140         )
    141         .with_field(field(
    142             "amount",
    143             "amount",
    144             RadrootsCoreDecimal::describe(ctx),
    145             "crates/core/src/quantity.rs",
    146             14,
    147         ))
    148         .with_field(field(
    149             "unit",
    150             "unit",
    151             unit,
    152             "crates/core/src/quantity.rs",
    153             16,
    154         ))
    155         .with_field(
    156             field(
    157                 "label",
    158                 "label",
    159                 <Option<String> as Dto>::describe(ctx),
    160                 "crates/core/src/quantity.rs",
    161                 18,
    162             )
    163             .with_presence(FieldPresence::optional_nullable_skip_if_none()),
    164         );
    165         register(ctx, "RadrootsCoreQuantity", TypeDef::Struct(def))
    166     }
    167 }
    168 
    169 impl Dto for RadrootsCoreQuantityPrice {
    170     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    171         let amount = RadrootsCoreMoney::describe(ctx);
    172         let quantity = RadrootsCoreQuantity::describe(ctx);
    173         let def = StructDef::new(
    174             "RadrootsCoreQuantityPrice",
    175             "RadrootsCoreQuantityPrice",
    176             span("crates/core/src/quantity_price.rs", 5),
    177         )
    178         .with_field(field(
    179             "amount",
    180             "amount",
    181             amount,
    182             "crates/core/src/quantity_price.rs",
    183             7,
    184         ))
    185         .with_field(field(
    186             "quantity",
    187             "quantity",
    188             quantity,
    189             "crates/core/src/quantity_price.rs",
    190             9,
    191         ));
    192         register(ctx, "RadrootsCoreQuantityPrice", TypeDef::Struct(def))
    193     }
    194 }
    195 
    196 impl Dto for RadrootsCoreDiscountScope {
    197     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    198         let def = EnumDef::new(
    199             "RadrootsCoreDiscountScope",
    200             "RadrootsCoreDiscountScope",
    201             EnumRepr::External,
    202             span("crates/core/src/discount.rs", 9),
    203         )
    204         .with_variant(unit_variant(
    205             "Bin",
    206             "bin",
    207             "crates/core/src/discount.rs",
    208             10,
    209         ))
    210         .with_variant(unit_variant(
    211             "OrderTotal",
    212             "order_total",
    213             "crates/core/src/discount.rs",
    214             11,
    215         ));
    216         register(ctx, "RadrootsCoreDiscountScope", TypeDef::Enum(def))
    217     }
    218 }
    219 
    220 impl Dto for RadrootsCoreDiscountThreshold {
    221     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    222         let quantity = RadrootsCoreQuantity::describe(ctx);
    223         let def = EnumDef::new(
    224             "RadrootsCoreDiscountThreshold",
    225             "RadrootsCoreDiscountThreshold",
    226             EnumRepr::Adjacent {
    227                 tag: "kind".to_owned(),
    228                 content: "amount".to_owned(),
    229             },
    230             span("crates/core/src/discount.rs", 20),
    231         )
    232         .with_variant(VariantDef::new(
    233             "BinCount",
    234             "bin_count",
    235             VariantShape::Struct(vec![
    236                 field(
    237                     "bin_id",
    238                     "bin_id",
    239                     String::describe(ctx),
    240                     "crates/core/src/discount.rs",
    241                     21,
    242                 ),
    243                 field(
    244                     "min",
    245                     "min",
    246                     u32::describe(ctx),
    247                     "crates/core/src/discount.rs",
    248                     21,
    249                 ),
    250             ]),
    251             span("crates/core/src/discount.rs", 21),
    252         ))
    253         .with_variant(VariantDef::new(
    254             "OrderQuantity",
    255             "order_quantity",
    256             VariantShape::Struct(vec![field(
    257                 "min",
    258                 "min",
    259                 quantity,
    260                 "crates/core/src/discount.rs",
    261                 22,
    262             )]),
    263             span("crates/core/src/discount.rs", 22),
    264         ));
    265         register(ctx, "RadrootsCoreDiscountThreshold", TypeDef::Enum(def))
    266     }
    267 }
    268 
    269 impl Dto for RadrootsCoreDiscountValue {
    270     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    271         let money = RadrootsCoreMoney::describe(ctx);
    272         let percent = RadrootsCorePercent::describe(ctx);
    273         let def = EnumDef::new(
    274             "RadrootsCoreDiscountValue",
    275             "RadrootsCoreDiscountValue",
    276             EnumRepr::Adjacent {
    277                 tag: "kind".to_owned(),
    278                 content: "amount".to_owned(),
    279             },
    280             span("crates/core/src/discount.rs", 31),
    281         )
    282         .with_variant(VariantDef::new(
    283             "MoneyPerBin",
    284             "money_per_bin",
    285             VariantShape::Newtype(money),
    286             span("crates/core/src/discount.rs", 32),
    287         ))
    288         .with_variant(VariantDef::new(
    289             "Percent",
    290             "percent",
    291             VariantShape::Newtype(percent),
    292             span("crates/core/src/discount.rs", 33),
    293         ));
    294         register(ctx, "RadrootsCoreDiscountValue", TypeDef::Enum(def))
    295     }
    296 }
    297 
    298 impl Dto for RadrootsCoreDiscount {
    299     fn describe(ctx: &mut DescribeCtx) -> TypeRef {
    300         let scope = RadrootsCoreDiscountScope::describe(ctx);
    301         let threshold = RadrootsCoreDiscountThreshold::describe(ctx);
    302         let value = RadrootsCoreDiscountValue::describe(ctx);
    303         let def = StructDef::new(
    304             "RadrootsCoreDiscount",
    305             "RadrootsCoreDiscount",
    306             span("crates/core/src/discount.rs", 39),
    307         )
    308         .with_field(field(
    309             "scope",
    310             "scope",
    311             scope,
    312             "crates/core/src/discount.rs",
    313             40,
    314         ))
    315         .with_field(field(
    316             "threshold",
    317             "threshold",
    318             threshold,
    319             "crates/core/src/discount.rs",
    320             41,
    321         ))
    322         .with_field(field(
    323             "value",
    324             "value",
    325             value,
    326             "crates/core/src/discount.rs",
    327             42,
    328         ));
    329         register(ctx, "RadrootsCoreDiscount", TypeDef::Struct(def))
    330     }
    331 }
    332 
    333 fn register(ctx: &mut DescribeCtx, rust_ident: &str, type_def: TypeDef) -> TypeRef {
    334     ctx.register_type(RustTypeId::new("radroots_core", rust_ident), type_def)
    335 }
    336 
    337 fn unit_variant(rust_name: &str, wire_name: &str, file: &str, line: u32) -> VariantDef {
    338     VariantDef::new(rust_name, wire_name, VariantShape::Unit, span(file, line))
    339 }
    340 
    341 fn field(rust_name: &str, wire_name: &str, ty: TypeRef, file: &str, line: u32) -> FieldDef {
    342     FieldDef::new(
    343         IdentName::new(rust_name),
    344         WireFieldNames::same(wire_name),
    345         TargetFieldNames::new(wire_name, rust_name),
    346         ty,
    347         span(file, line),
    348     )
    349 }
    350 
    351 fn span(file: &str, line: u32) -> SourceSpan {
    352     SourceSpan::new(file, line, 1)
    353 }
    354 
    355 #[cfg(test)]
    356 mod tests {
    357     use dto_bindgen_core::{TypeDef, build_registry};
    358 
    359     use super::dto_roots;
    360 
    361     #[test]
    362     fn core_descriptor_roots_build_registry() {
    363         let registry = build_registry(dto_roots());
    364 
    365         assert!(!registry.has_errors());
    366         assert_eq!(registry.roots.len(), dto_roots().len());
    367         assert!(registry.types_by_id.values().any(
    368             |def| matches!(def, TypeDef::Struct(def) if def.export_name == "RadrootsCoreMoney")
    369         ));
    370         assert!(
    371             registry.types_by_id.values().any(
    372                 |def| matches!(def, TypeDef::Enum(def) if def.export_name == "RadrootsCoreUnit")
    373             )
    374         );
    375     }
    376 }