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()))
}
}
}