use std::collections::{BTreeMap, HashMap};
use std::fmt;
use crate::parsing::ast::{ComponentDefinition, Type};
use crate::value::Value;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ComponentArgType {
String,
Bool,
Integer,
Float,
Number,
Array,
Map,
}
impl ComponentArgType {
pub fn as_str(&self) -> &'static str {
match self {
ComponentArgType::String => "string",
ComponentArgType::Bool => "bool",
ComponentArgType::Integer => "integer",
ComponentArgType::Float => "float",
ComponentArgType::Number => "number",
ComponentArgType::Array => "array",
ComponentArgType::Map => "map",
}
}
}
impl fmt::Display for ComponentArgType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl From<Type> for ComponentArgType {
fn from(t: Type) -> Self {
match t {
Type::String => ComponentArgType::String,
Type::Bool => ComponentArgType::Bool,
Type::Integer => ComponentArgType::Integer,
Type::Float => ComponentArgType::Float,
Type::Number => ComponentArgType::Number,
Type::Array => ComponentArgType::Array,
Type::Map => ComponentArgType::Map,
}
}
}
#[derive(Clone, Debug)]
pub struct ComponentArg {
name: String,
default: Option<Value>,
arg_type: Option<ComponentArgType>,
}
impl ComponentArg {
pub fn name(&self) -> &str {
&self.name
}
pub fn default(&self) -> Option<&Value> {
self.default.as_ref()
}
pub fn arg_type(&self) -> Option<ComponentArgType> {
self.arg_type
}
pub fn is_required(&self) -> bool {
self.default.is_none()
}
}
#[derive(Clone, Debug)]
pub struct ComponentInfo {
name: String,
args: Vec<ComponentArg>,
rest_param: Option<String>,
metadata: BTreeMap<String, Value>,
}
impl ComponentInfo {
pub fn name(&self) -> &str {
&self.name
}
pub fn args(&self) -> HashMap<&str, &ComponentArg> {
HashMap::from_iter(self.args.iter().map(|arg| (arg.name(), arg)))
}
pub fn rest_param(&self) -> Option<&str> {
self.rest_param.as_deref()
}
pub fn metadata(&self) -> &BTreeMap<String, Value> {
&self.metadata
}
}
impl From<&ComponentDefinition> for ComponentInfo {
fn from(def: &ComponentDefinition) -> Self {
let args = def
.kwargs
.iter()
.map(|(name, arg)| ComponentArg {
name: name.clone(),
default: arg.default.clone(),
arg_type: arg.typ.map(ComponentArgType::from),
})
.collect();
ComponentInfo {
name: def.name.clone(),
args,
rest_param: def.rest_param_name.clone(),
metadata: def.metadata.clone(),
}
}
}