use serde::{Deserialize, Serialize};
use lalrpop_util::lalrpop_mod;
lalrpop_mod!(script_syn);
#[derive(Serialize, Deserialize, Debug)]
pub struct Units(Vec<Unit>);
impl core::ops::Deref for Units {
type Target = Vec<Unit>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for Units {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Serialize, Deserialize)]
pub enum Unit {
KeyValue(Key, Value),
SingleValue(Value),
Questioned(Key, Value),
Relation(Key, String, Value),
}
#[derive(Serialize, Deserialize, Debug)]
pub enum Entry {
Ident(String),
RawStr(String),
}
#[derive(Serialize, Deserialize)]
pub struct Key(Entry);
impl core::ops::Deref for Key {
type Target = Entry;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl core::ops::DerefMut for Key {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[derive(Serialize, Deserialize)]
pub enum Value {
Empty,
Primitive(Entry),
Units(Box<Units>),
}
super::fn_parse_file!(Units, script_syn::UnitsParser);
pub mod types {
pub use super::{Entry, Key, Unit, Units, Value};
}
impl core::fmt::Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Value::Empty => write!(f, "{{}}"),
Value::Primitive(v) => write!(f, "{:?}", v),
Value::Units(v) => write!(f, "{:#?}", v),
}
}
}
impl core::fmt::Debug for Unit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Unit::KeyValue(k, v) => write!(f, "{:?} = {:?}", k.0, v),
Unit::SingleValue(v) => write!(f, "{:?}", v),
Unit::Questioned(k, v) => write!(f, "{:?} ?= {:?}", k.0, v),
Unit::Relation(k, r, v) => write!(f, "{:?} {} {:?}", k.0, r, v),
}
}
}
impl core::fmt::Display for Units {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.recursive_write(f, 0)
}
}
impl Units {
pub fn recursive_write(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
for unit in &self.0 {
unit.recursive_write(f, level)?;
writeln!(f)?;
}
Ok(())
}
}
impl Unit {
fn recursive_write(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
write!(f, "{}", " ".repeat(level))?;
match self {
Unit::KeyValue(k, v) => {
write!(f, "{} = ", k.0)?;
v.recursive_write(f, level + 1)
}
Unit::SingleValue(v) => v.recursive_write(f, level + 1),
Unit::Questioned(k, v) => {
write!(f, "{} ?= ", k.0)?;
v.recursive_write(f, level + 1)
}
Unit::Relation(k, r, v) => {
write!(f, "{} {} ", k.0, r)?;
v.recursive_write(f, level + 1)
}
}
}
}
impl Value {
fn recursive_write(&self, f: &mut std::fmt::Formatter<'_>, level: usize) -> std::fmt::Result {
match self {
Value::Empty => write!(f, "{{}}"),
Value::Primitive(v) => write!(f, "{}", v),
Value::Units(v) => {
writeln!(f, "{{")?;
v.recursive_write(f, level + 1)?;
write!(f, "{}}}", " ".repeat(level.saturating_sub(1)))
}
}
}
}
impl core::fmt::Display for Entry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
Entry::Ident(s) | Entry::RawStr(s) => write!(f, "{}", s),
}
}
}