2020-06-13 09:18:47 +02:00
use serde ::de ;
use serde ::de ::value ::MapDeserializer ;
use serde ::forward_to_deserialize_any ;
2020-06-20 22:08:33 +02:00
use std ::collections ::HashMap ;
2020-06-13 09:18:47 +02:00
mod error ;
2020-06-20 22:21:21 +02:00
use error ::{ Error , MpdResult } ;
mod structs ;
pub use structs ::Track ;
/// some unprintable character to separate repeated keys
const SEPARATOR : char = '\x02' ;
2020-06-13 09:18:47 +02:00
2020-06-13 09:44:26 +02:00
struct MPDeserializer < ' de , Iter : Iterator < Item = ( & ' de str , & ' de str ) > > {
2020-06-20 22:08:33 +02:00
inner : MapDeserializer < ' de , Iter , Error > ,
2020-06-13 09:18:47 +02:00
}
2020-06-13 09:44:26 +02:00
impl < ' de , Iter : Iterator < Item = ( & ' de str , & ' de str ) > > de ::Deserializer < ' de >
2020-06-13 09:18:47 +02:00
for MPDeserializer < ' de , Iter >
{
2020-06-20 22:08:33 +02:00
type Error = Error ;
2020-06-13 09:18:47 +02:00
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
}
}
2020-06-20 22:08:33 +02:00
fn deserialize_response < ' a , I : Iterator < Item = & ' a str > > ( input : I ) -> Result < Track , Error > {
let mut map : HashMap < String , String > = HashMap ::new ( ) ;
2020-06-20 17:14:07 +02:00
for line in input {
2020-06-20 22:08:33 +02:00
if line . starts_with ( " OK " ) {
2020-06-20 17:14:07 +02:00
break ;
} else if let Some ( message ) = line . strip_prefix ( " ACK " ) {
2020-06-20 22:08:33 +02:00
return Err ( Error ::from_str ( message . trim ( ) ) ) ;
2020-06-20 17:14:07 +02:00
}
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 ( ) ) ;
}
2020-06-13 09:18:47 +02:00
}
2020-06-20 17:14:07 +02:00
_ = > panic! ( " invalid response line: {:?} " , line ) ,
2020-06-13 09:18:47 +02:00
}
}
2020-06-20 17:14:07 +02:00
return Ok ( envy ::from_iter ( map ) . unwrap ( ) ) ;
2020-06-20 22:21:21 +02:00
// Eventually, I’d like to use my own deserializer instead of envy
2020-06-20 17:14:07 +02:00
// let deser = MPDeserializer {
// inner: MapDeserializer::new(map.into_iter()),
// };
// Song::deserialize(deser)
}
fn main ( ) {
2020-06-20 22:08:33 +02:00
let input_str = " file: Youtube Rip/VVVVVV Medley.flac
2020-06-20 17:14:07 +02:00
Last - Modified : 2018 - 03 - 07 T13 :18 :01 Z
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 ( ) ) ;
2020-06-20 22:21:21 +02:00
println! ( " {:?} " , s ) ;
2020-06-13 09:18:47 +02:00
}