oo_bindgen/model/builder/
enums.rs1use std::collections::HashSet;
2
3use crate::model::*;
4
5pub struct EnumBuilder<'a> {
6 lib: &'a mut LibraryBuilder,
7 name: Name,
8 variants: Vec<EnumVariant<Unvalidated>>,
9 variant_names: HashSet<String>,
10 variant_values: HashSet<i32>,
11 next_value: i32,
12 doc: OptionalDoc,
13}
14
15impl<'a> EnumBuilder<'a> {
16 pub(crate) fn new(lib: &'a mut LibraryBuilder, name: Name) -> Self {
17 Self {
18 lib,
19 name: name.clone(),
20 variants: Vec::new(),
21 variant_names: HashSet::new(),
22 variant_values: HashSet::new(),
23 next_value: 0,
24 doc: OptionalDoc::new(name),
25 }
26 }
27
28 pub fn variant<T: IntoName, D: Into<Doc<Unvalidated>>>(
29 mut self,
30 name: T,
31 value: i32,
32 doc: D,
33 ) -> BindResult<Self> {
34 let name = name.into_name()?;
35 let unique_name = self.variant_names.insert(name.to_string());
36 let unique_value = self.variant_values.insert(value);
37 if unique_name && unique_value {
38 self.variants.push(EnumVariant {
39 name,
40 value,
41 doc: doc.into(),
42 });
43 self.next_value = value + 1;
44 Ok(self)
45 } else if !unique_name {
46 Err(BindingErrorVariant::DuplicateEnumVariantName {
47 name: self.name,
48 variant_name: name.to_string(),
49 }
50 .into())
51 } else {
52 Err(BindingErrorVariant::DuplicateEnumVariantValue {
53 name: self.name,
54 variant_value: value,
55 }
56 .into())
57 }
58 }
59
60 pub fn push<T: IntoName, D: Into<Doc<Unvalidated>>>(self, name: T, doc: D) -> BindResult<Self> {
61 let value = self.next_value;
62 self.variant(name.into_name()?, value, doc)
63 }
64
65 pub fn doc<D: Into<Doc<Unvalidated>>>(mut self, doc: D) -> BindResult<Self> {
66 self.doc.set(doc.into())?;
67 Ok(self)
68 }
69
70 pub(crate) fn build_and_release(
71 self,
72 ) -> BindResult<(Handle<Enum<Unvalidated>>, &'a mut LibraryBuilder)> {
73 let handle = Handle::new(Enum {
74 name: self.name,
75 settings: self.lib.clone_settings(),
76 variants: self.variants,
77 doc: self.doc.extract()?,
78 });
79
80 self.lib
81 .add_statement(Statement::EnumDefinition(handle.clone()))?;
82
83 Ok((handle, self.lib))
84 }
85
86 pub fn build(self) -> BindResult<Handle<Enum<Unvalidated>>> {
87 let (ret, _) = self.build_and_release()?;
88 Ok(ret)
89 }
90}