1use crate::primitives::Primitive;
2use std::{collections::BTreeMap, hash::Hash};
3use syn::{Item, TypeParam, TypeParamBound};
4
5mod cargo_dependency;
6mod custom_type;
7mod enums;
8mod structs;
9mod type_ident;
10
11pub use cargo_dependency::CargoDependency;
12pub use custom_type::CustomType;
13pub use enums::{Enum, EnumOptions, Variant, VariantAttrs};
14pub use structs::{Field, FieldAttrs, Struct, StructOptions};
15pub use type_ident::TypeIdent;
16
17pub type TypeMap = BTreeMap<TypeIdent, Type>;
18
19#[derive(Clone, Debug, Eq, Hash, PartialEq)]
20pub enum Type {
21 Alias(String, TypeIdent),
22 Array(Primitive, usize),
23 Container(String, TypeIdent),
24 Custom(CustomType),
25 Enum(Enum),
26 List(String, TypeIdent),
27 Map(String, TypeIdent, TypeIdent),
28 Primitive(Primitive),
29 String,
30 Struct(Struct),
31 Tuple(Vec<TypeIdent>),
32 Unit,
33}
34
35impl Type {
36 pub fn from_item(item_str: &str) -> Self {
37 let item = syn::parse_str::<Item>(item_str).unwrap();
38 match item {
39 Item::Enum(item) => Type::Enum(enums::parse_enum_item(item)),
40 Item::Struct(item) => Type::Struct(structs::parse_struct_item(item)),
41 item => panic!(
42 "Only struct and enum types can be constructed from an item. Found: {:?}",
43 item
44 ),
45 }
46 }
47
48 pub fn name(&self) -> String {
49 match self {
50 Self::Alias(name, _) => name.clone(),
51 Self::Array(primitive, size) => format!("[{}; {}]", primitive.name(), size),
52 Self::Container(name, ident) => format!("{name}<{ident}>"),
53 Self::Custom(custom) => custom.ident.to_string(),
54 Self::Enum(Enum { ident, .. }) => ident.to_string(),
55 Self::List(name, ident) => format!("{name}<{ident}>"),
56 Self::Map(name, key, value) => format!("{name}<{key}, {value}>"),
57 Self::Primitive(primitive) => primitive.name(),
58 Self::String => "String".to_owned(),
59 Self::Struct(Struct { ident, .. }) => ident.to_string(),
60 Self::Tuple(items) => format!(
61 "({})",
62 items
63 .iter()
64 .map(ToString::to_string)
65 .collect::<Vec<_>>()
66 .join(", ")
67 ),
68 Self::Unit => "()".to_owned(),
69 }
70 }
71}
72
73pub(crate) fn format_bounds(ty: &TypeParam) -> Vec<String> {
74 ty.bounds
75 .iter()
76 .filter_map(|bound| match bound {
77 TypeParamBound::Trait(tr) => Some(path_to_string(&tr.path)),
78 _ => None,
79 })
80 .collect()
81}
82
83fn path_to_string(path: &syn::Path) -> String {
84 path.segments
85 .iter()
86 .map(|segment| segment.ident.to_string())
87 .collect::<Vec<_>>()
88 .join("::")
89}
90
91pub(crate) fn is_runtime_bound(bound: &str) -> bool {
94 bound != "Serializable" && bound != "fp_bindgen::prelude::Serializable"
96}