lib.rs (3756B)
1 pub use radroots_types as upstream; 2 3 use dto_bindgen_core::{ 4 DescribeCtx, Dto, FieldDef, GenericParam, IdentName, Primitive, RootDescriptor, RustTypeId, 5 SourceSpan, StructDef, TargetFieldNames, TypeDef, TypeRef, WireFieldNames, 6 }; 7 8 struct IErrorDto; 9 struct IResultDto; 10 struct IResultListDto; 11 struct IResultPassDto; 12 13 pub fn dto_roots() -> Vec<RootDescriptor> { 14 vec![ 15 RootDescriptor::new::<IErrorDto>(), 16 RootDescriptor::new::<IResultDto>(), 17 RootDescriptor::new::<IResultListDto>(), 18 RootDescriptor::new::<IResultPassDto>(), 19 ] 20 } 21 22 impl Dto for IErrorDto { 23 fn describe(ctx: &mut DescribeCtx) -> TypeRef { 24 ctx.register_type( 25 rust_id("IError"), 26 generic_struct("IError", "err", TypeRef::GenericParam("T".to_owned())), 27 ) 28 } 29 } 30 31 impl Dto for IResultDto { 32 fn describe(ctx: &mut DescribeCtx) -> TypeRef { 33 ctx.register_type( 34 rust_id("IResult"), 35 generic_struct("IResult", "result", TypeRef::GenericParam("T".to_owned())), 36 ) 37 } 38 } 39 40 impl Dto for IResultListDto { 41 fn describe(ctx: &mut DescribeCtx) -> TypeRef { 42 ctx.register_type( 43 rust_id("IResultList"), 44 generic_struct( 45 "IResultList", 46 "results", 47 TypeRef::vec(TypeRef::GenericParam("T".to_owned())), 48 ), 49 ) 50 } 51 } 52 53 impl Dto for IResultPassDto { 54 fn describe(ctx: &mut DescribeCtx) -> TypeRef { 55 ctx.register_type( 56 rust_id("IResultPass"), 57 TypeDef::Struct( 58 StructDef::new("IResultPass", "IResultPass", source_span()) 59 .with_field(field("pass", TypeRef::Primitive(Primitive::Bool))), 60 ), 61 ) 62 } 63 } 64 65 fn generic_struct(export_name: &str, field_name: &str, field_type: TypeRef) -> TypeDef { 66 let mut def = StructDef::new(export_name, export_name, source_span()) 67 .with_field(field(field_name, field_type)); 68 def.generics.push(GenericParam::new("T")); 69 TypeDef::Struct(def) 70 } 71 72 fn field(name: &str, ty: TypeRef) -> FieldDef { 73 FieldDef::new( 74 IdentName::new(name), 75 WireFieldNames::same(name), 76 TargetFieldNames::new(name, name), 77 ty, 78 source_span(), 79 ) 80 } 81 82 fn rust_id(name: &'static str) -> RustTypeId { 83 RustTypeId::new(env!("CARGO_PKG_NAME"), name) 84 } 85 86 fn source_span() -> SourceSpan { 87 SourceSpan::new(file!(), line!(), column!()) 88 } 89 90 #[cfg(test)] 91 mod tests { 92 use super::dto_roots; 93 use dto_bindgen_core::{TypeDef, TypeRef, build_registry}; 94 95 #[test] 96 fn preserves_result_wrapper_roots() { 97 let registry = build_registry(dto_roots()); 98 let actual = registry 99 .types_by_id 100 .values() 101 .map(|type_def| match type_def { 102 TypeDef::Struct(def) => def.export_name.as_str(), 103 TypeDef::Enum(def) => def.export_name.as_str(), 104 }) 105 .collect::<Vec<_>>(); 106 107 assert_eq!(actual, ["IError", "IResult", "IResultList", "IResultPass"]); 108 } 109 110 #[test] 111 fn preserves_generic_result_wrapper_fields() { 112 let registry = build_registry(dto_roots()); 113 let result_list = registry 114 .types_by_id 115 .values() 116 .find_map(|type_def| match type_def { 117 TypeDef::Struct(def) if def.export_name == "IResultList" => Some(def), 118 _ => None, 119 }) 120 .expect("IResultList descriptor"); 121 122 assert_eq!(result_list.generics[0].name, "T"); 123 assert_eq!(result_list.fields[0].target.typescript, "results"); 124 assert_eq!( 125 result_list.fields[0].ty, 126 TypeRef::vec(TypeRef::GenericParam("T".to_owned())) 127 ); 128 } 129 }