alef 0.115.12

Opinionated polyglot binding generator for Rust libraries
Documentation
use std::collections::HashSet;
use std::sync::Arc;

pub(super) trait OptionalFieldSet {
    fn contains(&self, name: &str) -> bool;
}

impl OptionalFieldSet for HashSet<String> {
    fn contains(&self, name: &str) -> bool {
        HashSet::contains(self, name)
    }
}

#[derive(Clone, Default)]
pub(super) struct OptionalFields {
    shared: Arc<HashSet<String>>,
    local: HashSet<String>,
}

impl From<HashSet<String>> for OptionalFields {
    fn from(local: HashSet<String>) -> Self {
        Self {
            shared: Arc::default(),
            local,
        }
    }
}

impl OptionalFields {
    pub(super) fn contains(&self, name: &str) -> bool {
        self.shared.contains(name) || self.local.contains(name)
    }

    pub(super) fn iter(&self) -> impl Iterator<Item = &String> {
        self.shared
            .iter()
            .chain(self.local.iter().filter(|name| !self.shared.contains(*name)))
    }

    pub(super) fn insert(&mut self, name: String) {
        if !self.shared.contains(&name) {
            self.local.insert(name);
        }
    }

    pub(super) fn extend(&mut self, names: HashSet<String>) {
        self.include_shared(Arc::new(names));
    }

    pub(super) fn include_shared(&mut self, names: Arc<HashSet<String>>) {
        if self.shared.is_empty() {
            self.shared = names;
        } else if !Arc::ptr_eq(&self.shared, &names) {
            self.shared = Arc::new(self.shared.iter().chain(names.iter()).cloned().collect());
        }
    }
}

impl OptionalFieldSet for OptionalFields {
    fn contains(&self, name: &str) -> bool {
        self.contains(name)
    }
}