simploxide_bindgen/types/
enum_type.rs

1use super::TopLevelDocs;
2
3use convert_case::{Case, Casing as _};
4use std::str::FromStr;
5
6pub struct EnumType {
7    pub name: String,
8    pub variants: Vec<EnumVariant>,
9    pub doc_comments: Vec<String>,
10    pub syntax: String,
11}
12
13impl EnumType {
14    pub fn new(name: String, variants: Vec<EnumVariant>) -> Self {
15        Self {
16            name,
17            variants,
18            doc_comments: Vec::new(),
19            syntax: String::new(),
20        }
21    }
22}
23
24impl TopLevelDocs for EnumType {
25    fn doc_lines(&self) -> &Vec<String> {
26        &self.doc_comments
27    }
28
29    fn syntax(&self) -> &str {
30        self.syntax.as_str()
31    }
32}
33
34impl std::fmt::Display for EnumType {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        self.write_docs_fmt(f)?;
37
38        writeln!(
39            f,
40            "#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]"
41        )?;
42        writeln!(f, "#[non_exhaustive]")?;
43        writeln!(f, "pub enum {} {{", self.name)?;
44        writeln!(f, "    #[default]")?;
45
46        for var in &self.variants {
47            writeln!(f, "    #[serde(rename = \"{}\")]", var.api_name)?;
48            writeln!(f, "    {},", var.rust_name)?;
49        }
50
51        writeln!(f, "}}")
52    }
53}
54
55pub struct EnumVariant {
56    pub api_name: String,
57    pub rust_name: String,
58}
59
60impl EnumVariant {
61    pub fn from_api_name(api_name: &str) -> Self {
62        Self {
63            api_name: api_name.to_owned(),
64            rust_name: api_name.to_case(Case::Pascal),
65        }
66    }
67}
68
69impl FromStr for EnumVariant {
70    type Err = String;
71
72    fn from_str(s: &str) -> Result<Self, Self::Err> {
73        if !s.starts_with('"') || !s.ends_with('"') {
74            return Err(format!("'{s}' is not an enum variant name"));
75        }
76
77        let api_name = s.trim_matches('"').to_owned();
78        let rust_name = api_name.to_case(Case::Pascal);
79
80        Ok(Self {
81            api_name,
82            rust_name,
83        })
84    }
85}