oo-bindgen 0.8.0

DSL-based binding geneator for C, C++, Java, and C#
Documentation
use std::collections::HashSet;

use crate::model::*;

pub struct EnumBuilder<'a> {
    lib: &'a mut LibraryBuilder,
    name: Name,
    variants: Vec<EnumVariant<Unvalidated>>,
    variant_names: HashSet<String>,
    variant_values: HashSet<i32>,
    next_value: i32,
    doc: OptionalDoc,
}

impl<'a> EnumBuilder<'a> {
    pub(crate) fn new(lib: &'a mut LibraryBuilder, name: Name) -> Self {
        Self {
            lib,
            name: name.clone(),
            variants: Vec::new(),
            variant_names: HashSet::new(),
            variant_values: HashSet::new(),
            next_value: 0,
            doc: OptionalDoc::new(name),
        }
    }

    pub fn variant<T: IntoName, D: Into<Doc<Unvalidated>>>(
        mut self,
        name: T,
        value: i32,
        doc: D,
    ) -> BindResult<Self> {
        let name = name.into_name()?;
        let unique_name = self.variant_names.insert(name.to_string());
        let unique_value = self.variant_values.insert(value);
        if unique_name && unique_value {
            self.variants.push(EnumVariant {
                name,
                value,
                doc: doc.into(),
            });
            self.next_value = value + 1;
            Ok(self)
        } else if !unique_name {
            Err(BindingErrorVariant::DuplicateEnumVariantName {
                name: self.name,
                variant_name: name.to_string(),
            }
            .into())
        } else {
            Err(BindingErrorVariant::DuplicateEnumVariantValue {
                name: self.name,
                variant_value: value,
            }
            .into())
        }
    }

    pub fn push<T: IntoName, D: Into<Doc<Unvalidated>>>(self, name: T, doc: D) -> BindResult<Self> {
        let value = self.next_value;
        self.variant(name.into_name()?, value, doc)
    }

    pub fn doc<D: Into<Doc<Unvalidated>>>(mut self, doc: D) -> BindResult<Self> {
        self.doc.set(doc.into())?;
        Ok(self)
    }

    pub(crate) fn build_and_release(
        self,
    ) -> BindResult<(Handle<Enum<Unvalidated>>, &'a mut LibraryBuilder)> {
        let handle = Handle::new(Enum {
            name: self.name,
            settings: self.lib.clone_settings(),
            variants: self.variants,
            doc: self.doc.extract()?,
        });

        self.lib
            .add_statement(Statement::EnumDefinition(handle.clone()))?;

        Ok((handle, self.lib))
    }

    pub fn build(self) -> BindResult<Handle<Enum<Unvalidated>>> {
        let (ret, _) = self.build_and_release()?;
        Ok(ret)
    }
}