Skip to content

Commit c8f05af

Browse files
author
David Rajchenbach-Teller
committed
Introducing MultiPart support for serialization
1 parent c222794 commit c8f05af

File tree

7 files changed

+291
-288
lines changed

7 files changed

+291
-288
lines changed

src/api.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//!
1414
//!
1515
16+
use serialize::*;
1617
use services::*;
1718
use selector::*;
1819
pub use util::{ ResultMap, TargetMap, Targetted };
@@ -57,14 +58,14 @@ pub enum Error {
5758
}
5859

5960
impl ToJSON for Error {
60-
fn to_json(&self) -> JSON {
61+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
6162
let mut serializer = Serializer::new();
6263
match self.serialize(&mut serializer) {
6364
// FIXME: I don't think that this can explode, but there doesn't seem to
6465
// be any way to check :/
6566
Ok(()) => serializer.unwrap(),
6667
Err(_) =>
67-
vec![("Internal error while serializing", "")].to_json()
68+
vec![("Internal error while serializing", "")].to_json(parts)
6869
}
6970
}
7071
}

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ pub mod api;
2121
/// Tools for parsing from JSON.
2222
pub mod parse;
2323

24+
/// Tools for converting values to a format that may be sent.
25+
pub mod serialize;
26+
2427
/// Selecting one or more devices. Exposed through the API.
2528
pub mod selector;
2629

src/parse.rs

Lines changed: 0 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
//! Utilities for defining a JSON parser.
22
3-
use util::Id;
4-
53
use std::cell::RefCell;
6-
use std::collections::{ HashMap, HashSet };
74
use std::error::Error as StdError;
85
use std::fmt::{ Display, Debug, Error as FmtError, Formatter };
9-
use std::hash::Hash;
106
use std::rc::Rc;
117
use std::sync::Arc;
128

@@ -355,106 +351,6 @@ impl<T> Parser<Arc<T>> for Arc<T> where T: Parser<T> {
355351
}
356352
}
357353

358-
pub trait ToJSON {
359-
fn to_json(&self) -> JSON;
360-
}
361-
362-
impl ToJSON for String {
363-
fn to_json(&self) -> JSON {
364-
JSON::String(self.clone())
365-
}
366-
}
367-
368-
impl ToJSON for bool {
369-
fn to_json(&self) -> JSON {
370-
JSON::Bool(*self)
371-
}
372-
}
373-
374-
impl ToJSON for f64 {
375-
fn to_json(&self) -> JSON {
376-
JSON::F64(*self)
377-
}
378-
}
379-
380-
impl ToJSON for usize {
381-
fn to_json(&self) -> JSON {
382-
JSON::U64(*self as u64)
383-
}
384-
}
385-
386-
impl ToJSON for JSON {
387-
fn to_json(&self) -> JSON {
388-
self.clone()
389-
}
390-
}
391-
392-
impl<T> ToJSON for HashSet<T> where T: ToJSON + Eq + Hash {
393-
fn to_json(&self) -> JSON {
394-
JSON::Array((*self).iter().map(T::to_json).collect())
395-
}
396-
}
397-
398-
impl<T> ToJSON for HashMap<String, T> where T: ToJSON {
399-
fn to_json(&self) -> JSON {
400-
JSON::Object(self.iter().map(|(k, v)| (k.clone(), T::to_json(v))).collect())
401-
}
402-
}
403-
404-
impl<T> ToJSON for Vec<T> where T: ToJSON {
405-
fn to_json(&self) -> JSON {
406-
JSON::Array(self.iter().map(|x| x.to_json()).collect())
407-
}
408-
}
409-
410-
impl<'a, T> ToJSON for Vec<(&'a str, T)> where T: ToJSON {
411-
fn to_json(&self) -> JSON {
412-
JSON::Object(self.iter().map(|&(ref k, ref v)| {
413-
((*k).to_owned(), v.to_json())
414-
}).collect())
415-
}
416-
}
417-
418-
impl <'a> ToJSON for &'a str {
419-
fn to_json(&self) -> JSON {
420-
JSON::String((*self).to_owned())
421-
}
422-
}
423-
424-
impl<'a, T> ToJSON for &'a T where T: ToJSON {
425-
fn to_json(&self) -> JSON {
426-
(**self).to_json()
427-
}
428-
}
429-
430-
impl<K, T, V> ToJSON for HashMap<Id<K>, Result<T, V>> where T: ToJSON, V: ToJSON {
431-
fn to_json(&self) -> JSON {
432-
JSON::Object(self.iter().map(|(k, result)| {
433-
let k = k.to_string();
434-
let result = match *result {
435-
Ok(ref ok) => ok.to_json(),
436-
Err(ref err) => vec![("Error", err)].to_json()
437-
};
438-
(k, result)
439-
}).collect())
440-
}
441-
}
442-
443-
impl<T> ToJSON for Option<T> where T: ToJSON {
444-
fn to_json(&self) -> JSON {
445-
match *self {
446-
None => JSON::Null,
447-
Some(ref result) => result.to_json()
448-
}
449-
}
450-
}
451-
452-
impl ToJSON for () {
453-
fn to_json(&self) -> JSON {
454-
JSON::Null
455-
}
456-
}
457-
458354
/*
459355
impl<T> Parser<T> for T where T: Deserialize {
460356
fn parse(_: Path, source: &mut JSON) -> Result<T, ParseError> {

src/serialize.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
//! Utilities for serializing data to JSON.
2+
use util::*;
3+
4+
use std::collections::{ BTreeMap, HashMap, HashSet };
5+
use std::hash::Hash;
6+
7+
use serde_json::value::Value as JSON;
8+
9+
/// A store to put binary parts.
10+
pub trait BinaryParts {
11+
fn push(&mut self, mimetype: Id<MimeTypeId>, binary: &[u8]) -> JSON;
12+
}
13+
14+
/// An imnplementation of `MultiPart` that stores everything in a HashMap and returns
15+
/// JSON objects `"{part: i}"`, where `i` is the (integer) key in the HashMap.
16+
pub struct MultiPart {
17+
pub buf: Vec<(Id<MimeTypeId>, Vec<u8>)>,
18+
}
19+
impl MultiPart {
20+
pub fn new() -> Self {
21+
MultiPart {
22+
buf: Vec::new(),
23+
}
24+
}
25+
}
26+
impl BinaryParts for MultiPart {
27+
fn push(&mut self, mimetype: Id<MimeTypeId>, binary: &[u8]) -> JSON {
28+
let mut vec = Vec::with_capacity(binary.len());
29+
vec.extend_from_slice(binary);
30+
self.buf.push((mimetype, vec));
31+
let mut map = BTreeMap::new();
32+
map.insert("part".to_owned(), JSON::U64(self.buf.len() as u64));
33+
JSON::Object(map)
34+
}
35+
}
36+
37+
pub trait ToJSON {
38+
fn to_json(&self, parts: &mut BinaryParts) -> JSON;
39+
}
40+
41+
impl ToJSON for String {
42+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
43+
JSON::String(self.clone())
44+
}
45+
}
46+
47+
impl ToJSON for bool {
48+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
49+
JSON::Bool(*self)
50+
}
51+
}
52+
53+
impl ToJSON for f64 {
54+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
55+
JSON::F64(*self)
56+
}
57+
}
58+
59+
impl ToJSON for usize {
60+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
61+
JSON::U64(*self as u64)
62+
}
63+
}
64+
65+
impl ToJSON for JSON {
66+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
67+
self.clone()
68+
}
69+
}
70+
71+
impl<T> ToJSON for HashSet<T> where T: ToJSON + Eq + Hash {
72+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
73+
JSON::Array((*self).iter().map(|x| x.to_json(parts)).collect())
74+
}
75+
}
76+
77+
impl<T> ToJSON for HashMap<String, T> where T: ToJSON {
78+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
79+
JSON::Object(self.iter().map(|(k, v)| (k.clone(), T::to_json(v, parts))).collect())
80+
}
81+
}
82+
83+
impl<T> ToJSON for Vec<T> where T: ToJSON {
84+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
85+
JSON::Array(self.iter().map(|x| x.to_json(parts)).collect())
86+
}
87+
}
88+
89+
impl<'a, T> ToJSON for Vec<(&'a str, T)> where T: ToJSON {
90+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
91+
JSON::Object(self.iter().map(|&(ref k, ref v)| {
92+
((*k).to_owned(), v.to_json(parts))
93+
}).collect())
94+
}
95+
}
96+
97+
impl <'a> ToJSON for &'a str {
98+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
99+
JSON::String((*self).to_owned())
100+
}
101+
}
102+
103+
impl<'a, T> ToJSON for &'a T where T: ToJSON {
104+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
105+
(**self).to_json(parts)
106+
}
107+
}
108+
109+
impl<K, T, V> ToJSON for HashMap<Id<K>, Result<T, V>> where T: ToJSON, V: ToJSON {
110+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
111+
JSON::Object(self.iter().map(|(k, result)| {
112+
let k = k.to_string();
113+
let result = match *result {
114+
Ok(ref ok) => ok.to_json(parts),
115+
Err(ref err) => vec![("Error", err)].to_json(parts)
116+
};
117+
(k, result)
118+
}).collect())
119+
}
120+
}
121+
122+
impl<T> ToJSON for Option<T> where T: ToJSON {
123+
fn to_json(&self, parts: &mut BinaryParts) -> JSON {
124+
match *self {
125+
None => JSON::Null,
126+
Some(ref result) => result.to_json(parts)
127+
}
128+
}
129+
}
130+
131+
impl ToJSON for () {
132+
fn to_json(&self, _: &mut BinaryParts) -> JSON {
133+
JSON::Null
134+
}
135+
}

0 commit comments

Comments
 (0)