oo_bindgen/model/builder/
enums.rs

1use 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}