simploxide_bindgen/types/
enum_type.rs1use 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}