reda-lib 0.1.0

Liberty file library
Documentation
pub mod parse;
pub use parse::parse_liberty;

use crate::error::LibError;

#[derive(Debug, Clone, PartialEq)]
pub enum Ast {
    Group {
        kind: String,
        params: Vec<String>,
        items: Vec<Ast>,
    },
    Attr {
        key: String,
        value: Value,
    },
}

#[derive(Debug, Clone, PartialEq)]
pub enum Value {
    Bool(bool),
    Float(f64),
    FloatGroup(Vec<f64>),
    String(String),
    Ident(String),
    Vec(Vec<Value>),
}

impl Ast {
    pub fn group(kind: impl Into<String>, params: impl Into<Vec<String>>, items: impl Into<Vec<Ast>>) -> Self {
        Self::Group {
            kind: kind.into(),
            params: params.into(),
            items: items.into(),
        }
    }

    pub fn group_single_param(kind: impl Into<String>, param: impl Into<String>, items: impl Into<Vec<Ast>>) -> Self {
        Self::Group {
            kind: kind.into(),
            params: vec![param.into()],
            items: items.into(),
        }
    }

    pub fn attr(key: impl Into<String>, value: impl Into<Value>) -> Self {
        Self::Attr { key: key.into(), value: value.into() }
    }
}

impl Value {
    pub fn kind_str(&self) -> &'static str {
        match self {
            Self::Bool(_) => "bool",
            Self::Float(_) => "float",
            Self::FloatGroup(_) => "floats",
            Self::Ident(_) => "ident",
            Self::String(_) => "string",
            Self::Vec(_) => "vector",
        }
    }

    pub fn bool(&self) -> Result<bool, LibError> {
        if let Self::Bool(value) = self {
            Ok(*value)
        } else {
            Err(LibError::ValueKindUnmatch("bool", self.kind_str()))
        }
    }

    pub fn float(&self) -> Result<f64, LibError> {
        if let Self::Float(value) = self {
            Ok(*value)
        } else {
            Err(LibError::ValueKindUnmatch("float", self.kind_str()))
        }
    }

    pub fn floats(&self) -> Result<&[f64], LibError> {
        if let Self::FloatGroup(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("floats", self.kind_str()))
        }
    }

    pub fn ident(&self) -> Result<&str, LibError> {
        if let Self::Ident(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("ident", self.kind_str()))
        }
    }

    pub fn string(&self) -> Result<&str, LibError> {
        if let Self::String(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("string", self.kind_str()))
        }
    }

    pub fn vector(&self) -> Result<&[Value], LibError> {
        if let Self::Vec(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("vector", self.kind_str()))
        }
    }
}

impl Value {
    pub fn into_bool(self) -> Result<bool, LibError> {
        if let Self::Bool(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("bool", self.kind_str()))
        }
    }

    pub fn into_float(self) -> Result<f64, LibError> {
        if let Self::Float(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("float", self.kind_str()))
        }
    }

    pub fn into_floats(self) -> Result<Vec<f64>, LibError> {
        if let Self::FloatGroup(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("floats", self.kind_str()))
        }
    }

    pub fn into_ident(self) -> Result<String, LibError> {
        if let Self::Ident(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("ident", self.kind_str()))
        }
    }

    pub fn into_string(self) -> Result<String, LibError> {
        if let Self::String(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("string", self.kind_str()))
        }
    }

    pub fn into_vector(self) -> Result<Vec<Value>, LibError> {
        if let Self::Vec(value) = self {
            Ok(value)
        } else {
            Err(LibError::ValueKindUnmatch("vector", self.kind_str()))
        }
    }
}