106 lines
2.8 KiB
Rust
106 lines
2.8 KiB
Rust
#[macro_use]
|
|
extern crate pest_derive;
|
|
use pest::iterators::Pair;
|
|
use pest::Parser;
|
|
use serde::de;
|
|
use serde::de::value::MapDeserializer;
|
|
use serde::de::DeserializeOwned;
|
|
use serde::forward_to_deserialize_any;
|
|
use serde::Deserialize;
|
|
mod error;
|
|
use error::MpdResult;
|
|
|
|
#[derive(Parser)]
|
|
#[grammar = "response.pest"]
|
|
struct MpdParser;
|
|
|
|
struct MPDeserializer<'de, Iter: Iterator<Item = (String, String)>> {
|
|
inner: MapDeserializer<'de, Iter, error::Error>,
|
|
}
|
|
|
|
impl<'de, Iter: Iterator<Item = (String, String)>> de::Deserializer<'de>
|
|
for MPDeserializer<'de, Iter>
|
|
{
|
|
type Error = error::Error;
|
|
|
|
fn deserialize_any<V>(self, visitor: V) -> MpdResult<V::Value>
|
|
where
|
|
V: de::Visitor<'de>,
|
|
{
|
|
self.deserialize_map(visitor)
|
|
}
|
|
|
|
fn deserialize_map<V>(self, visitor: V) -> MpdResult<V::Value>
|
|
where
|
|
V: de::Visitor<'de>,
|
|
{
|
|
visitor.visit_map(self.inner)
|
|
}
|
|
|
|
forward_to_deserialize_any! {
|
|
bool char str string bytes byte_buf unit unit_struct seq
|
|
tuple tuple_struct struct identifier ignored_any
|
|
i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 option newtype_struct enum
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct Song {
|
|
Title: String,
|
|
Artist: String,
|
|
}
|
|
|
|
const input_var: &str = "Title: A song 星
|
|
Artist: A name
|
|
OK mpd 0.21.23";
|
|
|
|
fn main() {
|
|
/*
|
|
let parsed = MpdParser::parse(Rule::response, input)
|
|
.expect("invalid response")
|
|
.next()
|
|
.unwrap();
|
|
let last = parsed.into_inner().last().unwrap();
|
|
match last.as_rule() {
|
|
Rule::ok => println!("response was ok"),
|
|
Rule::err => println!("response was an error"),
|
|
_ => unreachable!("Last response line should always be a status"),
|
|
}
|
|
let mut deser = MPDeserializer::from_str(
|
|
"Title: A song 星
|
|
Artist: A name
|
|
OK mpd 0.21.23",
|
|
)
|
|
.expect("broken deser");
|
|
let d = Song::deserialize(&mut deser);
|
|
println!("{:?}", d);
|
|
*/
|
|
let mut map = std::collections::HashMap::new();
|
|
let parser = MpdParser::parse(Rule::response, input_var)
|
|
.unwrap()
|
|
.next()
|
|
.unwrap();
|
|
for pair in parser.into_inner() {
|
|
let rule = pair.as_rule();
|
|
match rule {
|
|
Rule::kv => {
|
|
let mut fields = pair.into_inner();
|
|
map.insert(
|
|
fields.next().unwrap().as_str().to_string(),
|
|
fields.next().unwrap().as_str().to_string(),
|
|
);
|
|
}
|
|
Rule::ok => (),
|
|
Rule::err => panic!("received error response"),
|
|
_ => unreachable!(),
|
|
}
|
|
}
|
|
// ::<'_, _, Song>
|
|
dbg!(&map);
|
|
let deser = MPDeserializer {
|
|
inner: serde::de::value::MapDeserializer::new(map.into_iter()),
|
|
};
|
|
let s = Song::deserialize(deser);
|
|
println!("{:?}", s);
|
|
}
|