use geo_aid_derive::Parse;
use num_traits::Zero;
use crate::script::builtins;
use std::{
    fmt::{Debug, Display},
    iter::Peekable,
    marker::PhantomData,
};
use crate::span;
use super::{
    token::{
        number::CompExponent, Ampersant, Asterisk, At, Caret, Colon, Comma, Dollar, Dot, Eq,
        Exclamation, Gt, Gteq, Ident, LBrace, LParen, LSquare, Let, Lt, Lteq, Minus, NamedIdent,
        Number, Plus, Question, RBrace, RParen, RSquare, Semi, Slash, Span, StrLit, TokInteger,
        Token,
    },
    unit, ComplexUnit, Error,
};
pub trait Parse {
    type FirstToken: CheckParses;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized;
    fn get_span(&self) -> Span;
}
pub trait CheckParses {
    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &InputStream<'t, I>,
    ) -> Option<bool>;
}
impl<T: Parse> CheckParses for T {
    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &InputStream<'t, I>,
    ) -> Option<bool> {
        Some(input.clone().parse::<Self>().is_ok())
    }
}
#[derive(Debug)]
pub struct TokenOr<T, U> {
    phantom_t: PhantomData<T>,
    phantom_u: PhantomData<U>,
}
impl<T: CheckParses, U: CheckParses> CheckParses for TokenOr<T, U> {
    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &InputStream<'t, I>,
    ) -> Option<bool> {
        T::check_parses(input).or_else(|| U::check_parses(input))
    }
}
#[derive(Debug)]
pub struct Maybe<T> {
    phantom_t: PhantomData<T>,
}
impl<T: CheckParses> CheckParses for Maybe<T> {
    fn check_parses<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &InputStream<'t, I>,
    ) -> Option<bool> {
        T::check_parses(input).and_then(|x| if x { Some(x) } else { None })
    }
}
impl<T: Parse> Parse for Vec<T> {
    type FirstToken = Maybe<T::FirstToken>;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let mut parsed = Self::new();
        while let Ok(Some(v)) = input.parse() {
            parsed.push(v);
        }
        Ok(parsed)
    }
    fn get_span(&self) -> Span {
        self.first().map_or(Span::empty(), |x| {
            x.get_span().join(self.last().unwrap().get_span())
        })
    }
}
impl<T: Parse, U: Parse> Parse for (T, U) {
    type FirstToken = T::FirstToken;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized,
    {
        Ok((input.parse()?, input.parse()?))
    }
    fn get_span(&self) -> Span {
        self.0.get_span().join(self.1.get_span())
    }
}
impl<T: Parse> Parse for Option<T> {
    type FirstToken = Maybe<T::FirstToken>;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized,
    {
        if T::FirstToken::check_parses(input) == Some(false) {
            Ok(None)
        } else {
            Ok(Some(input.parse()?))
        }
    }
    fn get_span(&self) -> Span {
        match self {
            Some(v) => v.get_span(),
            None => span!(0, 0, 0, 0),
        }
    }
}
#[derive(Debug, Clone)]
pub struct InputStream<'t, I: Iterator<Item = &'t Token> + Clone> {
    it: Peekable<I>,
}
impl<'t, I: Iterator<Item = &'t Token> + Clone> InputStream<'t, I> {
    #[must_use]
    pub fn new<It: IntoIterator<IntoIter = I>>(it: It) -> Self {
        Self {
            it: it.into_iter().peekable(),
        }
    }
    pub fn parse<P: Parse>(&mut self) -> Result<P, Error> {
        P::parse(self)
    }
    pub fn get_token(&mut self) -> Result<&'t Token, Error> {
        self.it.next().ok_or(Error::EndOfInput)
    }
    pub fn expect_token(&mut self) -> Result<(), Error> {
        if self.eof() {
            Err(Error::EndOfInput)
        } else {
            Ok(())
        }
    }
    #[must_use]
    pub fn eof(&mut self) -> bool {
        self.it.peek().is_none()
    }
}
#[derive(Debug, Parse)]
pub enum BinaryOperator {
    Add(Plus),
    Sub(Minus),
    Mul(Asterisk),
    Div(Slash),
}
impl ToString for BinaryOperator {
    fn to_string(&self) -> String {
        match self {
            BinaryOperator::Add(_) => String::from("+"),
            BinaryOperator::Sub(_) => String::from("-"),
            BinaryOperator::Mul(_) => String::from("*"),
            BinaryOperator::Div(_) => String::from("/"),
        }
    }
}
#[derive(Debug, Parse)]
#[parse(first_token = Ampersant)]
pub struct PointCollectionConstructor {
    pub ampersant: Ampersant,
    pub left_paren: LParen,
    pub points: Punctuated<Expression<false>, Comma>,
    pub right_paren: RParen,
}
#[derive(Debug)]
pub struct ImplicitIterator<const ITER: bool> {
    pub exprs: Punctuated<SimpleExpression, Comma>,
}
impl<const ITER: bool> ImplicitIterator<ITER> {
    #[must_use]
    pub fn get(&self, index: usize) -> Option<&SimpleExpression> {
        if ITER {
            self.exprs.get(index)
        } else {
            Some(&self.exprs.first)
        }
    }
}
impl<const ITER: bool> Parse for ImplicitIterator<ITER> {
    type FirstToken = <SimpleExpression as Parse>::FirstToken;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized,
    {
        if ITER {
            Ok(Self {
                exprs: input.parse()?,
            })
        } else {
            Ok(Self {
                exprs: Punctuated {
                    first: input.parse()?,
                    collection: Vec::new(),
                },
            })
        }
    }
    fn get_span(&self) -> Span {
        self.exprs.get_span()
    }
}
#[derive(Debug)]
pub struct ExplicitIterator {
    pub dollar: Dollar,
    pub id_token: TokInteger,
    pub id: u8,
    pub left_paren: LParen,
    pub exprs: Punctuated<Expression<false>, Comma>,
    pub right_paren: RParen,
}
impl ExplicitIterator {
    #[must_use]
    pub fn get(&self, index: usize) -> Option<&Expression<false>> {
        self.exprs.get(index)
    }
}
impl Parse for ExplicitIterator {
    type FirstToken = Dollar;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        let mut parsed = Self {
            dollar: input.parse()?,
            id_token: input.parse()?,
            id: 0,
            left_paren: input.parse()?,
            exprs: input.parse()?,
            right_paren: input.parse()?,
        };
        parsed.id = parsed
            .id_token
            .parsed
            .parse()
            .map_err(|_| Error::NumberTooLarge {
                error_span: parsed.id_token.get_span(),
            })?;
        if parsed.exprs.len() == 1 {
            return Err(Error::SingleVariantExplicitIterator {
                error_span: parsed.dollar.span.join(parsed.right_paren.span),
            });
        }
        Ok(parsed)
    }
    fn get_span(&self) -> Span {
        self.dollar.span.join(self.right_paren.span)
    }
}
#[derive(Debug)]
pub enum Expression<const ITER: bool> {
    ImplicitIterator(ImplicitIterator<ITER>),
    Binop(ExprBinop<ITER>),
}
impl<const ITER: bool> Parse for Expression<ITER> {
    type FirstToken = <SimpleExpression as Parse>::FirstToken;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        let mut expr = Expression::ImplicitIterator(input.parse()?);
        while let Ok(Some(op)) = input.parse() {
            let rhs = Expression::ImplicitIterator(input.parse()?);
            expr = dispatch_order(expr, op, rhs);
        }
        Ok(expr)
    }
    fn get_span(&self) -> Span {
        match self {
            Expression::ImplicitIterator(it) => it.get_span(),
            Expression::Binop(e) => e.lhs.get_span().join(e.rhs.get_span()),
        }
    }
}
#[derive(Debug)]
pub struct RationalExponent {
    pub lparen: LParen,
    pub nom: TokInteger,
    pub slash: Slash,
    pub denom: TokInteger,
    pub rparen: RParen,
}
impl Parse for RationalExponent {
    type FirstToken = LParen;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        let parsed = Self {
            lparen: input.parse()?,
            nom: input.parse()?,
            slash: input.parse()?,
            denom: input.parse()?,
            rparen: input.parse()?,
        };
        if parsed.denom.parsed.is_zero() {
            return Err(Error::ZeroDenominator {
                error_span: parsed.denom.span,
            });
        }
        Ok(parsed)
    }
    fn get_span(&self) -> Span {
        self.lparen.span.join(self.rparen.span)
    }
}
#[derive(Debug, Parse)]
pub enum Exponent {
    Simple(TokInteger),
    Parenthised(RationalExponent),
}
impl Exponent {
    pub fn into_comp(&self) -> Result<CompExponent, Error> {
        match self {
            Self::Simple(i) => Ok(CompExponent::new(
                i.parsed
                    .parse()
                    .map_err(|_| Error::NumberTooLarge { error_span: i.span })?,
                1,
            )),
            Self::Parenthised(exp) => Ok(CompExponent::new(
                exp.nom.parsed.parse().map_err(|_| Error::NumberTooLarge {
                    error_span: exp.nom.span,
                })?,
                exp.denom
                    .parsed
                    .parse()
                    .map_err(|_| Error::NumberTooLarge {
                        error_span: exp.denom.span,
                    })?,
            )),
        }
    }
}
#[derive(Debug, Parse)]
pub struct Exponentiation {
    pub caret: Caret,
    pub minus: Option<Minus>,
    pub exponent: Exponent,
}
#[derive(Debug, Parse)]
pub struct FieldIndex {
    pub name: Box<Name>,
    pub dot: Dot,
    pub field: Ident,
}
#[derive(Debug)]
pub enum Name {
    Call(ExprCall),
    FieldIndex(FieldIndex),
    Ident(Ident),
    Expression(ExprParenthised),
}
impl Parse for Name {
    type FirstToken = TokenOr<Maybe<Ident>, LParen>;
    fn parse<'t, I: Iterator<Item = &'t Token> + Clone>(
        input: &mut InputStream<'t, I>,
    ) -> Result<Self, Error>
    where
        Self: Sized,
    {
        let mut name = if let Some(expr) = input.parse()? {
            Self::Expression(expr)
        } else {
            Self::Ident(input.parse()?)
        };
        loop {
            name = if let Some(dot) = input.parse::<Option<Dot>>()? {
                Self::FieldIndex(FieldIndex {
                    name: Box::new(name),
                    dot,
                    field: input.parse()?,
                })
            } else if let Some(lparen) = input.parse::<Option<LParen>>()? {
                Self::Call(ExprCall {
                    name: Box::new(name),
                    lparen,
                    params: input.parse()?,
                    rparen: input.parse()?,
                })
            } else {
                break Ok(name);
            };
        }
    }
    fn get_span(&self) -> Span {
        match self {
            Self::Call(v) => v.get_span(),
            Self::FieldIndex(v) => v.get_span(),
            Self::Expression(v) => v.get_span(),
            Self::Ident(v) => v.get_span(),
        }
    }
}
#[derive(Debug, Parse)]
pub struct SimpleExpression {
    pub minus: Option<Minus>,
    pub kind: SimpleExpressionKind,
    pub exponent: Option<Exponentiation>,
    pub display: Option<DisplayProperties>,
}
#[derive(Debug, Parse)]
pub enum SimpleExpressionKind {
    Name(Name),
    Number(Number),
    ExplicitIterator(ExplicitIterator),
    PointCollection(PointCollectionConstructor),
}
#[derive(Debug, Parse)]
pub struct ExprCall {
    pub name: Box<Name>,
    pub lparen: LParen,
    pub params: Option<Punctuated<Expression<false>, Comma>>,
    pub rparen: RParen,
}
#[derive(Debug, Parse)]
pub struct ExprParenthised {
    pub lparen: LParen,
    pub content: Box<Expression<true>>,
    pub rparen: RParen,
}
#[derive(Debug, Parse)]
pub struct ExprBinop<const ITER: bool> {
    pub lhs: Box<Expression<ITER>>,
    pub operator: BinaryOperator,
    pub rhs: Box<Expression<ITER>>,
}
impl BinaryOperator {
    fn index(&self) -> u8 {
        match self {
            BinaryOperator::Add(_) | BinaryOperator::Sub(_) => 1,
            BinaryOperator::Mul(_) | BinaryOperator::Div(_) => 2,
        }
    }
}
fn dispatch_order<const ITER: bool>(
    lhs: Expression<ITER>,
    op: BinaryOperator,
    rhs: Expression<ITER>, ) -> Expression<ITER> {
    match lhs {
        lhs @ Expression::ImplicitIterator(_) => Expression::Binop(ExprBinop {
            lhs: Box::new(lhs),
            operator: op,
            rhs: Box::new(rhs),
        }),
        Expression::Binop(lhs) => {
            if op.index() > lhs.operator.index() {
                Expression::Binop(ExprBinop {
                    lhs: lhs.lhs,
                    operator: lhs.operator,
                    rhs: Box::new(dispatch_order(*lhs.rhs, op, rhs)),
                })
            } else {
                Expression::Binop(ExprBinop {
                    lhs: Box::new(Expression::Binop(lhs)),
                    operator: op,
                    rhs: Box::new(rhs),
                })
            }
        }
    }
}
#[derive(Debug, Parse)]
pub enum PredefinedRuleOperator {
    Eq(Eq),
    Lt(Lt),
    Gt(Gt),
    Lteq(Lteq),
    Gteq(Gteq),
}
#[derive(Debug, Parse)]
pub enum RuleOperator {
    Inverted(InvertedRuleOperator),
    Predefined(PredefinedRuleOperator),
    Defined(NamedIdent),
}
#[derive(Debug, Parse)]
#[parse(first_token = Exclamation)]
pub struct InvertedRuleOperator {
    pub exlamation: Exclamation,
    pub operator: Box<RuleOperator>,
}
#[derive(Debug, Parse)]
pub struct FlagName {
    pub at: At,
    pub name: Punctuated<NamedIdent, Dot>,
    pub colon: Colon,
}
#[derive(Debug, Parse)]
#[parse(first_token = LBrace)]
pub struct FlagSet {
    pub lbrace: LBrace,
    pub flags: Vec<FlagStatement>,
    pub rbrace: RBrace,
}
#[derive(Debug, Parse)]
pub enum FlagValue {
    Ident(NamedIdent),
    Set(FlagSet),
    Number(Number),
}
#[derive(Debug, Parse)]
pub struct FlagStatement {
    pub name: FlagName,
    pub value: FlagValue,
}
#[derive(Debug, Clone, Parse)]
pub struct VariableDefinition {
    pub name: Ident,
    pub display_properties: Option<DisplayProperties>,
}
#[derive(Debug, Parse)]
pub struct LetStatement {
    pub let_token: Let,
    pub ident: Punctuated<VariableDefinition, Comma>,
    pub eq: Eq,
    pub expr: Expression<true>,
    pub rules: Vec<(RuleOperator, Expression<true>)>,
    pub semi: Semi,
}
#[derive(Debug, Parse)]
pub struct RuleStatement {
    pub display: Option<DisplayProperties>,
    pub lhs: Expression<true>,
    pub op: RuleOperator,
    pub rhs: Expression<true>,
    pub semi: Semi,
}
#[derive(Debug, Parse)]
pub struct RefStatement {
    pub display: Option<DisplayProperties>,
    pub question: Question,
    pub operand: Expression<true>,
    pub semi: Semi,
}
#[derive(Debug, Parse)]
pub enum Statement {
    Noop(Semi),
    Let(LetStatement),
    Flag(FlagStatement),
    Ref(RefStatement),
    Rule(RuleStatement),
}
impl Statement {
    #[must_use]
    pub fn as_flag(&self) -> Option<&FlagStatement> {
        if let Self::Flag(v) = self {
            Some(v)
        } else {
            None
        }
    }
}
#[derive(Debug, Clone, Parse)]
pub struct Punctuated<T: Parse, P: Parse> {
    pub first: Box<T>,
    pub collection: Vec<(P, T)>,
}
impl<T: Parse, P: Parse> Punctuated<T, P> {
    #[must_use]
    pub fn new(first: T) -> Punctuated<T, P> {
        Self {
            first: Box::new(first),
            collection: Vec::new(),
        }
    }
    pub fn iter(&self) -> impl Iterator<Item = &T> {
        vec![self.first.as_ref()]
            .into_iter()
            .chain(self.collection.iter().map(|x| &x.1))
    }
    pub fn into_parsed_iter(self) -> impl Iterator<Item = T> {
        vec![*self.first]
            .into_iter()
            .chain(self.collection.into_iter().map(|x| x.1))
    }
    #[must_use]
    pub fn len(&self) -> usize {
        self.collection.len() + 1
    }
    #[must_use]
    pub fn is_empty(&self) -> bool {
        false
    }
    #[must_use]
    pub fn get(&self, index: usize) -> Option<&T> {
        match index {
            0 => Some(&self.first),
            _ => self.collection.get(index - 1).map(|x| &x.1),
        }
    }
}
impl Parse for TokInteger {
    type FirstToken = Number;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        match input.get_token()? {
            Token::Number(Number::Integer(tok)) => Ok(tok.clone()),
            t => Err(Error::InvalidToken { token: t.clone() }),
        }
    }
    fn get_span(&self) -> Span {
        self.span
    }
}
impl Parse for NamedIdent {
    type FirstToken = Ident;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        match input.get_token()? {
            Token::Ident(Ident::Named(named)) => Ok(named.clone()),
            t => Err(Error::InvalidToken { token: t.clone() }),
        }
    }
    fn get_span(&self) -> Span {
        self.span
    }
}
impl<T: Parse> Parse for Box<T> {
    type FirstToken = T::FirstToken;
    fn parse<'r, I: Iterator<Item = &'r Token> + Clone>(
        input: &mut InputStream<'r, I>,
    ) -> Result<Self, Error> {
        Ok(Box::new(input.parse()?))
    }
    fn get_span(&self) -> Span {
        (**self).get_span()
    }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Type {
    Point,
    Line,
    Scalar(Option<ComplexUnit>),
    PointCollection(usize),
    Circle,
    Bundle(&'static str),
    Unknown,
}
impl Type {
    #[must_use]
    pub fn as_scalar(&self) -> Option<&Option<ComplexUnit>> {
        if let Self::Scalar(v) = self {
            Some(v)
        } else {
            None
        }
    }
}
pub struct DefinedType {
    pub name: String,
}
impl Display for Type {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Point => write!(f, "Point"),
            Self::Line => write!(f, "Line"),
            Self::Scalar(unit) => match unit {
                Some(unit) => write!(f, "Scalar ({unit})"),
                None => write!(f, "Scalar (no unit)"),
            },
            Self::PointCollection(l) => write!(f, "Point collection ({l})"),
            Self::Circle => write!(f, "Circle"),
            Self::Bundle(name) => write!(f, "{name}"),
            Type::Unknown => write!(f, "undefined"),
        }
    }
}
impl Type {
    #[must_use]
    pub fn can_cast(&self, into: &Type) -> bool {
        match self {
            Type::Point => matches!(into, Type::Point | Type::PointCollection(1)),
            Type::Line => matches!(into, Type::Line),
            Type::Scalar(Some(unit1)) => {
                if let Type::Scalar(Some(unit2)) = into {
                    unit1 == unit2
                } else {
                    false
                }
            }
            Type::Scalar(None) => match into {
                Type::Scalar(unit) => match unit {
                    Some(unit) => unit.0[1].is_zero(), None => true,
                },
                _ => false,
            },
            Type::PointCollection(l) => match into {
                Type::Point => *l == 1,
                Type::Line => *l == 2,
                Type::Scalar(Some(u)) => *u == unit::DISTANCE && *l == 2,
                Type::PointCollection(v) => v == l || *v == 0,
                _ => false,
            },
            Type::Circle => matches!(into, Type::Circle),
            Type::Bundle(name) => {
                if into == self {
                    true
                } else if let Type::PointCollection(count) = into {
                    builtins::get_bundle_pc(name) == *count
                } else {
                    false
                }
            }
            Type::Unknown => false,
        }
    }
}
#[derive(Debug, Clone, Parse)]
pub struct Property {
    pub name: NamedIdent,
    pub eq: Eq,
    pub value: PropertyValue,
}
#[derive(Debug, Clone, Parse)]
pub enum PropertyValue {
    Number(Number),
    Ident(Ident),
    RawString(RawString),
    String(StrLit),
}
impl Display for PropertyValue {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Number(n) => write!(f, "{n}"),
            Self::Ident(i) => write!(f, "{i}"),
            Self::RawString(s) => write!(f, "!{}", s.lit),
            Self::String(s) => write!(f, "{s}"),
        }
    }
}
#[derive(Debug, Clone, Parse)]
pub struct RawString {
    pub excl: Exclamation,
    pub lit: StrLit,
}
pub trait FromProperty: Sized {
    fn from_property(property: PropertyValue) -> Result<Self, Error>;
}
impl<T: FromProperty> FromProperty for Result<T, Error> {
    fn from_property(property: PropertyValue) -> Result<Self, Error> {
        Ok(T::from_property(property))
    }
}
impl FromProperty for bool {
    fn from_property(property: PropertyValue) -> Result<Self, Error> {
        match property {
            PropertyValue::Ident(ident) => match ident {
                Ident::Named(ident) => match ident.ident.as_str() {
                    "enabled" | "on" | "true" | "yes" => Ok(true),
                    "disabled" | "off" | "false" | "no" => Ok(false),
                    _ => Err(Error::BooleanExpected {
                        error_span: ident.get_span(),
                    }),
                },
                Ident::Collection(_) => Err(Error::BooleanExpected {
                    error_span: ident.get_span(),
                }),
            },
            PropertyValue::Number(num) => match num {
                Number::Integer(i) => match i.parsed.parse::<u8>() {
                    Ok(0) => Ok(false),
                    Ok(1) => Ok(true),
                    _ => Err(Error::BooleanExpected { error_span: i.span }),
                },
                Number::Float(f) => Err(Error::BooleanExpected { error_span: f.span }),
            },
            PropertyValue::String(s) => match s.content.as_str() {
                "enabled" | "on" | "true" | "yes" => Ok(true),
                "disabled" | "off" | "false" | "no" => Ok(false),
                _ => Err(Error::BooleanExpected {
                    error_span: s.get_span(),
                }),
            },
            PropertyValue::RawString(s) => Err(Error::BooleanExpected {
                error_span: s.get_span(),
            }),
        }
    }
}
impl FromProperty for String {
    fn from_property(property: PropertyValue) -> Result<String, Error> {
        match property {
            PropertyValue::Ident(ident) => Ok(ident.to_string()),
            PropertyValue::Number(num) => Err(Error::StringExpected {
                error_span: num.get_span(),
            }),
            PropertyValue::RawString(s) => Ok(s.lit.content),
            PropertyValue::String(s) => Ok(s.content),
        }
    }
}
#[derive(Debug, Clone, Parse)]
pub struct DisplayProperties {
    pub lsquare: LSquare,
    pub properties: Punctuated<Property, Semi>,
    pub rsquare: RSquare,
}