1use crate::{ast::*, xkb::Rule};
2use derivative::Derivative;
3use pest_ast::FromPest;
4use shrinkwraprs::Shrinkwrap;
5
6#[derive(Derivative, Shrinkwrap, FromPest, Clone, PartialEq)]
7#[derivative(Debug = "transparent")]
8#[pest_ast(rule(Rule::ident))]
9pub struct Ident<'src> {
10 #[pest_ast(outer(with(span_into_str)))]
11 pub content: &'src str,
12}
13
14#[derive(Derivative, Shrinkwrap, FromPest, Clone, PartialEq)]
15#[derivative(Debug = "transparent")]
16#[pest_ast(rule(Rule::symbol_name))]
17pub struct Symbol<'src> {
18 #[pest_ast(outer(with(span_into_str)))]
19 pub content: &'src str,
20}
21
22#[derive(Derivative, Shrinkwrap, FromPest, Clone, PartialEq)]
23#[derivative(Debug = "transparent")]
24#[pest_ast(rule(Rule::group))]
25pub struct Group<'src> {
26 #[pest_ast(inner(with(span_into_str)))]
27 pub content: &'src str,
28}
29
30#[derive(Derivative, Shrinkwrap, FromPest, Clone, PartialEq)]
31#[derivative(Debug = "transparent")]
32#[pest_ast(rule(Rule::key_combo))]
33pub struct KeyCombo<'src> {
34 pub content: Vec<Ident<'src>>,
35}
36
37#[derive(Derivative, Shrinkwrap, Clone, PartialEq)]
38#[derivative(Debug = "transparent")]
39pub struct StringContent<'src> {
40 pub content: &'src str,
41}
42
43impl<'src> From<StringContent<'src>> for String {
44 fn from(x: StringContent<'src>) -> String {
45 x.content.to_owned()
46 }
47}
48
49impl<'a, 'src> From<&'a StringContent<'src>> for String {
50 fn from(x: &StringContent) -> String {
51 x.content.to_owned()
52 }
53}
54
55impl<'a> ::from_pest::FromPest<'a> for StringContent<'a> {
56 type Rule = Rule;
57 type FatalError = ::from_pest::Void;
58
59 fn from_pest(
60 pest: &mut ::from_pest::pest::iterators::Pairs<'a, Self::Rule>,
61 ) -> ::std::result::Result<Self, ::from_pest::ConversionError<::from_pest::Void>> {
62 let mut clone = pest.clone();
63 let pair = clone.next().ok_or(::from_pest::ConversionError::NoMatch)?;
64 if pair.as_rule() == Rule::string {
65 let mut inner = pair.into_inner();
66 let inner = &mut inner;
67 let mut inner = inner.clone();
68 let first_item = inner.next();
69 let this = if let Some(item) = first_item {
70 if item.as_rule() == Rule::string_content {
71 StringContent { content: item.as_str() }
72 } else {
73 return Err(::from_pest::ConversionError::NoMatch);
74 }
75 } else {
76 return Err(::from_pest::ConversionError::NoMatch);
77 };
78 if inner.next().is_some() {
79 log::trace!("extraneous token, current node: `string`");
80 return Err(::from_pest::ConversionError::NoMatch);
81 }
82 *pest = clone;
83 Ok(this)
84 } else {
85 Err(::from_pest::ConversionError::NoMatch)
86 }
87 }
88}
89
90#[derive(Derivative, FromPest, Clone, PartialEq)]
91#[derivative(Debug = "transparent")]
92#[pest_ast(rule(Rule::negation))]
93pub struct Negation<'src> {
94 pub content: Ident<'src>,
95}
96
97#[derive(Derivative, FromPest, Clone, PartialEq)]
98#[derivative(Debug)]
99#[pest_ast(rule(Rule::EOI))]
100pub(crate) struct EOI;