featurecomb 0.2.0

Define feature groups and enforce relations between Cargo features from your manifest
Documentation
//! Defines a minimal schema of [Cargo
//! manifests](https://doc.rust-lang.org/cargo/reference/manifest.html).
//! This avoids relying on an external dependency and significantly improves compile times.

use std::collections::HashMap;

use serde::Deserialize;

#[derive(Debug, Deserialize)]
pub struct Manifest<META> {
    pub package: Option<Package<META>>,
    pub features: Option<FeatureSet>,
}

impl<META: serde::de::DeserializeOwned> Manifest<META> {
    pub fn from_str(manifest: &str) -> Result<Self, Error> {
        toml::from_str(manifest).map_err(Error::Parse)
    }
}

#[derive(Debug, Deserialize)]
#[expect(clippy::zero_sized_map_values)]
pub struct FeatureSet(HashMap<String, serde::de::IgnoredAny>);

impl FeatureSet {
    pub fn contains_key(&self, key: &str) -> bool {
        self.0.contains_key(key)
    }
}

#[derive(Debug, Deserialize)]
pub struct Package<META> {
    pub metadata: Option<META>,
}

#[derive(Debug)]
pub enum Error {
    Parse(toml::de::Error),
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Parse(err) => write!(f, "could not parse manifest: {err}"),
        }
    }
}