1#![allow(missing_docs)]
3
4use bufstream::BufStream;
5
6use crate::convert::FromIter;
7use crate::error::{Error, ParseError, ProtoError, Result};
8use crate::reply::Reply;
9
10use std::fmt;
11use std::io::{self, Lines, Read, Write};
12use std::result::Result as StdResult;
13use std::str::FromStr;
14
15pub struct Pairs<I>(pub I);
16
17impl<I> Iterator for Pairs<I>
18where I: Iterator<Item = io::Result<String>>
19{
20 type Item = Result<(String, String)>;
21 fn next(&mut self) -> Option<Result<(String, String)>> {
22 let reply: Option<Result<Reply>> =
23 self.0.next().map(|v| v.map_err(Error::Io).and_then(|s| s.parse::<Reply>().map_err(Error::Parse)));
24 match reply {
25 Some(Ok(Reply::Pair(a, b))) => Some(Ok((a, b))),
26 None | Some(Ok(Reply::Ok)) => None,
27 Some(Ok(Reply::Ack(e))) => Some(Err(Error::Server(e))),
28 Some(Err(e)) => Some(Err(e)),
29 }
30 }
31}
32
33pub struct Maps<'a, I: 'a> {
34 pairs: &'a mut Pairs<I>,
35 sep: &'a str,
36 value: Option<String>,
37 done: bool,
38 first: bool,
39}
40
41impl<'a, I> Iterator for Maps<'a, I>
42where I: Iterator<Item = io::Result<String>>
43{
44 type Item = Result<Vec<(String, String)>>;
45 fn next(&mut self) -> Option<Result<Vec<(String, String)>>> {
46 if self.done {
47 return None;
48 }
49
50 let mut map = Vec::new();
51
52 if let Some(b) = self.value.take() {
53 map.push((self.sep.to_owned(), b));
54 }
55
56 loop {
57 match self.pairs.next() {
58 Some(Ok((a, b))) => {
59 if &*a == self.sep {
60 self.value = Some(b);
61 if self.first {
62 self.first = false;
63 return self.next();
64 }
65 break;
66 } else {
67 map.push((a, b));
68 }
69 }
70 Some(Err(e)) => return Some(Err(e)),
71 None => {
72 self.done = true;
73 break;
74 }
75 }
76 }
77
78 if map.is_empty() {
79 None
80 } else {
81 Some(Ok(map))
82 }
83 }
84}
85
86impl<I> Pairs<I>
87where I: Iterator<Item = io::Result<String>>
88{
89 pub fn split<'a, 'b: 'a>(&'a mut self, f: &'b str) -> Maps<'a, I> {
90 Maps { pairs: self, sep: f, value: None, done: false, first: true }
91 }
92}
93
94#[doc(hidden)]
96pub trait Proto {
97 type Stream: Read + Write;
98
99 fn read_bytes(&mut self, bytes: usize) -> Result<Vec<u8>>;
100 fn read_line(&mut self) -> Result<String>;
101 fn read_pairs(&mut self) -> Pairs<Lines<&mut BufStream<Self::Stream>>>;
102
103 fn run_command<I>(&mut self, command: &str, arguments: I) -> Result<()>
104 where I: ToArguments;
105
106 fn read_structs<'a, T>(&'a mut self, key: &'static str) -> Result<Vec<T>>
107 where T: 'a + FromIter {
108 self.read_pairs().split(key).map(|v| v.and_then(|v| FromIter::from_iter(v.into_iter().map(Ok)))).collect()
109 }
110
111 fn read_list(&mut self, key: &'static str) -> Result<Vec<String>> {
112 self.read_pairs().filter(|r| r.as_ref().map(|(a, _)| *a == key).unwrap_or(true)).map(|r| r.map(|(_, b)| b)).collect()
113 }
114
115 fn read_struct<'a, T>(&'a mut self) -> Result<T>
116 where
117 T: 'a + FromIter,
118 Self::Stream: 'a,
119 {
120 FromIter::from_iter(self.read_pairs())
121 }
122
123 fn drain(&mut self) -> Result<()> {
124 loop {
125 let reply = self.read_line()?;
126 match &*reply {
127 "OK" | "list_OK" => break,
128 _ => (),
129 }
130 }
131 Ok(())
132 }
133
134 fn expect_ok(&mut self) -> Result<()> {
135 let line = self.read_line()?;
136
137 match line.parse::<Reply>() {
138 Ok(Reply::Ok) => Ok(()),
139 Ok(Reply::Ack(e)) => Err(Error::Server(e)),
140 Ok(_) => Err(Error::Proto(ProtoError::NotOk)),
141 Err(e) => Err(From::from(e)),
142 }
143 }
144
145 fn read_pair(&mut self) -> Result<(String, String)> {
146 let line = self.read_line()?;
147
148 match line.parse::<Reply>() {
149 Ok(Reply::Pair(a, b)) => Ok((a, b)),
150 Ok(Reply::Ok) => Err(Error::Proto(ProtoError::NotPair)),
151 Ok(Reply::Ack(e)) => Err(Error::Server(e)),
152 Err(e) => Err(Error::Parse(e)),
153 }
154 }
155
156 fn read_field<T: FromStr>(&mut self, field: &'static str) -> Result<T>
157 where ParseError: From<T::Err> {
158 let (a, b) = self.read_pair()?;
159 self.expect_ok()?;
160 if &*a == field {
161 Ok(b.parse::<T>().map_err(Into::<ParseError>::into)?)
162 } else {
163 Err(Error::Proto(ProtoError::NoField(field)))
164 }
165 }
166}
167
168pub trait ToArguments {
169 fn to_arguments<F, E>(&self, _: &mut F) -> StdResult<(), E>
170 where F: FnMut(&str) -> StdResult<(), E>;
171}
172
173impl ToArguments for () {
174 fn to_arguments<F, E>(&self, _: &mut F) -> StdResult<(), E>
175 where F: FnMut(&str) -> StdResult<(), E> {
176 Ok(())
177 }
178}
179
180impl<'a> ToArguments for &'a str {
181 fn to_arguments<F, E>(&self, f: &mut F) -> StdResult<(), E>
182 where F: FnMut(&str) -> StdResult<(), E> {
183 f(self)
184 }
185}
186
187macro_rules! argument_for_display {
188 ( $x:path ) => {
189 impl ToArguments for $x {
190 fn to_arguments<F, E>(&self, f: &mut F) -> StdResult<(), E>
191 where F: FnMut(&str) -> StdResult<(), E> {
192 f(&self.to_string())
193 }
194 }
195 };
196}
197argument_for_display! {i8}
198argument_for_display! {u8}
199argument_for_display! {u32}
200argument_for_display! {f32}
201argument_for_display! {f64}
202argument_for_display! {usize}
203argument_for_display! {crate::status::ReplayGain}
204argument_for_display! {String}
205argument_for_display! {crate::song::Id}
206argument_for_display! {crate::song::Range}
207argument_for_display! {crate::message::Channel}
208
209macro_rules! argument_for_tuple {
210 ( $($t:ident: $T: ident),+ ) => {
211 impl<$($T : ToArguments,)*> ToArguments for ($($T,)*) {
212 fn to_arguments<F, E>(&self, f: &mut F) -> StdResult<(), E>
213 where F: FnMut(&str) -> StdResult<(), E>
214 {
215 let ($(ref $t,)*) = *self;
216 $(
217 $t.to_arguments(f)?;
218 )*
219 Ok(())
220 }
221 }
222 };
223}
224argument_for_tuple! {t0: T0}
225argument_for_tuple! {t0: T0, t1: T1}
226argument_for_tuple! {t0: T0, t1: T1, t2: T2}
227argument_for_tuple! {t0: T0, t1: T1, t2: T2, t3: T3}
228argument_for_tuple! {t0: T0, t1: T1, t2: T2, t3:T3, t4: T4}
229
230impl<'a, T: ToArguments> ToArguments for &'a [T] {
231 fn to_arguments<F, E>(&self, f: &mut F) -> StdResult<(), E>
232 where F: FnMut(&str) -> StdResult<(), E> {
233 for arg in *self {
234 arg.to_arguments(f)?
235 }
236 Ok(())
237 }
238}
239
240pub struct Quoted<'a, D: fmt::Display + 'a + ?Sized>(pub &'a D);
241
242impl<'a, D: fmt::Display + 'a + ?Sized> fmt::Display for Quoted<'a, D> {
243 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
244 let unquoted = format!("{}", self.0);
245 if unquoted.is_empty() {
246 }
248 let quoted = unquoted.replace('\\', r"\\").replace('"', r#"\""#);
249 formatter.write_fmt(format_args!("\"{}\"", "ed))
250 }
251}
252
253