mparsed/src/main.rs

88 lines
2.5 KiB
Rust

use serde::de;
use serde::de::value::MapDeserializer;
use serde::forward_to_deserialize_any;
use std::collections::HashMap;
mod error;
use error::{Error, MpdResult};
mod structs;
pub use structs::Track;
/// some unprintable character to separate repeated keys
const SEPARATOR: char = '\x02';
struct MPDeserializer<'de, Iter: Iterator<Item = (&'de str, &'de str)>> {
inner: MapDeserializer<'de, Iter, Error>,
}
impl<'de, Iter: Iterator<Item = (&'de str, &'de str)>> de::Deserializer<'de>
for MPDeserializer<'de, Iter>
{
type 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
}
}
fn deserialize_response<'a, I: Iterator<Item = &'a str>>(input: I) -> Result<Track, Error> {
let mut map: HashMap<String, String> = HashMap::new();
for line in input {
if line.starts_with("OK") {
break;
} else if let Some(message) = line.strip_prefix("ACK") {
return Err(Error::from_str(message.trim()));
}
let mut fields = line.splitn(2, ": ");
match (fields.next(), fields.next()) {
(Some(k), Some(v)) => {
if let Some(existing) = map.get_mut(k) {
existing.push(SEPARATOR);
existing.push_str(v);
} else {
map.insert(k.to_string(), v.to_string());
}
}
_ => panic!("invalid response line: {:?}", line),
}
}
return Ok(envy::from_iter(map).unwrap());
// Eventually, I’d like to use my own deserializer instead of envy
// let deser = MPDeserializer {
// inner: MapDeserializer::new(map.into_iter()),
// };
// Song::deserialize(deser)
}
fn main() {
let input_str = "file: Youtube Rip/VVVVVV Medley.flac
Last-Modified: 2018-03-07T13:18:01Z
Album: VVVVVV OST / PPPPPP
Artist: FamilyJules7x
Composer: Magnus Pålsson
Date: 2014
Genre: Video Game Music
Title: VVVVVV Medley
Time: 433
duration: 432.727
Pos: 1548
Id: 1549";
let s = deserialize_response(input_str.lines());
println!("{:?}", s);
}