├── .gitignore ├── Cargo.toml ├── FORMAT.org ├── README.org ├── src ├── atom.rs ├── de.rs ├── error.rs ├── iter.rs ├── lib.rs ├── macros.rs ├── number.rs ├── read.rs ├── ser.rs └── sexp │ ├── de.rs │ ├── from.rs │ ├── index.rs │ ├── mod.rs │ └── ser.rs └── tests └── test.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | vendor/ 4 | _site/ 5 | 6 | # for personal testing 7 | src/main.rs 8 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sexpr" 3 | version = "0.7.0" 4 | authors = ["Zephyr Pellerin "] 5 | license = "MIT/Apache-2.0" 6 | description = "Multi-format S-expression serialization/deserialization support" 7 | repository = "https://github.com/zv/sexpr" 8 | keywords = ["sexp","s-exp","sexpr","smtlib"] 9 | categories = ["encoding"] 10 | readme = "README.org" 11 | documentation = "https://zv.github.io/rust/sexpr" 12 | 13 | [dependencies] 14 | serde = "1.0" 15 | num-traits = "0.1.32" 16 | itoa = "0.3" 17 | dtoa = "0.4" 18 | 19 | [dev-dependencies] 20 | serde_bytes = "0.10" 21 | serde_derive = "1.0" 22 | 23 | [[bin]] 24 | name = "main" 25 | doc = false 26 | 27 | -------------------------------------------------------------------------------- /FORMAT.org: -------------------------------------------------------------------------------- 1 | * A Canonical S-Expression Format 2 | In a 2012 Dr. Dobb's retrospective, Karl Eiger noted that S-expressions are 3 | have been in continuous use longer than any other formats that remain in widespread use today. 4 | 5 | * Formatting Parameters 6 | ** ~dotted_pair~ 7 | A variety of structures like hash tables can be serialized as basic lists or 8 | as a list of dotted-pair cons cells. 9 | 10 | Values: 11 | - ~true~ 12 | - ~false~ 13 | 14 | 15 | ** ~format_nil~ 16 | Nil is traditionally encoded as the empty list (=()=), however this can lead 17 | to problems in structures which need to serialize fields like 18 | ~Option>~, where both ~None~ and ~Some([])~ will serialize to the 19 | empty list. 20 | 21 | Possible values: 22 | - ~empty_list~ :: =()= 23 | - ~hash~ :: =#nil= 24 | - ~nul~ :: =nul= 25 | 26 | *)) Types 27 | ** Hash Tables 28 | #+BEGIN_SRC rust 29 | let ht = HashMap::new(); 30 | ht.insert("APPLES", 1); 31 | ht.insert("ORANGE", 2); 32 | ht.insert("STRAWBERRIES", 3); 33 | #+END_SRC 34 | 35 | *** Basic 36 | : ((APPLES 1) (ORANGES 2) (STRAWBERRIES 3)) 37 | : ((APPLES . 1) (ORANGES . 2) (STRAWBERRIES . 3)) 38 | 39 | *** Explicit (distinguishes between data structures) 40 | : ((variant HashMap) ((APPLES 1) (ORANGES 2) (STRAWBERRIES 3))) 41 | 42 | *** Initializer 43 | : (dict ((APPLES 1) 44 | : (ORANGES 2) 45 | : (STRAWBERRIES 3))) 46 | 47 | *** Keyword #:REQUIRES keyword 48 | : ((:APPLES 1 :ORANGES 2 :STRAWBERRIES 3)) 49 | 50 | ** Struct 51 | 52 | *** Simple 53 | #+BEGIN_SRC rust 54 | struct Color { 55 | r: u8, 56 | g: u8, 57 | b: u8, 58 | } 59 | 60 | Color { r: 254, g: 1, b: 10 } 61 | #+END_SRC 62 | 63 | **** Basic 64 | : ((r 254) (g 1) (b 10)) 65 | 66 | **** Explicit 67 | : ((variant Color) ((r 254) (g 1) (b 10))) 68 | 69 | **** Initializer 70 | : (Color :r 254 :g 1 :b 10) 71 | 72 | *** Option 73 | #+BEGIN_SRC rust 74 | struct Foo { 75 | x: Option 76 | } 77 | 78 | Foo { x: None } 79 | Foo { x: Some(5) } 80 | #+END_SRC 81 | 82 | **** Basic 83 | The representation of =#nil= can be configured. 84 | : ((x 5)) 85 | : ((x #nil)) 86 | 87 | **** Explicit 88 | : ((variant Foo) (x None)) 89 | : ((variant Foo) (x 5)) 90 | 91 | *** Simple 92 | #+BEGIN_SRC rust 93 | (1,2,3) 94 | #+END_SRC 95 | **** Basic 96 | : (1 2 3) 97 | **** Explicit 98 | : ((_field0 1) (_field1 2) (_field2 3)) 99 | 100 | ** Vec or &[u8] 101 | #+BEGIN_SRC rust 102 | &[41, 41, 19, 1] 103 | #+END_SRC 104 | *** Basic 105 | : (41 41 19 1) 106 | 107 | *** Lisp 108 | : #(41 41 19 1) 109 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | * sexpr: A S-expression library for Rust 2 | sexpr strives to be the canonical library for reading, manipulating and 3 | writing S-expressions in Rust. 4 | 5 | The parser is fully featured, performant and can be configured to read almost 6 | any s-expression variant including "/Standard/", "/Advanced/" and 7 | "/Canonical/" formats. 8 | 9 | Predefined compatibility configurations exist for a dozen standards and 10 | protocols including: 11 | 12 | - Standard 13 | - RFC 2693-compatible SPKI 14 | - SMTLIB & SMTLIBv2 15 | - GPG / libgcrypt 16 | - KiCad 17 | - R5RS-compatible abstract-syntax 18 | 19 | Individual format options can be enabled or disabled, allowing you to parse 20 | virtually any variant. 21 | 22 | # * Overview 23 | # S-expressions are data structures for representing complex data. They are 24 | # either primitives ("atoms") or lists of simpler S-expressions. Here is a 25 | # sample S-expression: 26 | 27 | # ~(snicker "abc" (#03# |YWJj|))~ 28 | 29 | # It is a list of length three: 30 | 31 | # - the octet-string "=snicker=" 32 | 33 | # - the octet-string "=abc=" 34 | 35 | # - a sub-list containing two elements: 36 | # - the hexadecimal constant =#03#= 37 | # - the base-64 constant =|YWJj|= (which is the same as "=abc=") 38 | 39 | # ** Should I use S-expressions as my serialization format? 40 | # Despite rapidly shifting technological landscapes and even faster changing 41 | # attitudes about 'proper' programming. S-expressions, and their many variants, 42 | # remain ([[http://www-formal.stanford.edu/jmc/recursive/recursive.html][as one of the oldest general encoding formats still in use today]]). 43 | 44 | # In spite of numerous challengers like JSON and XML, S-expressions retain the 45 | # advantages laid out by early computing and internetworking pioneers: 46 | 47 | # - Generality :: S-expressions are good at representing arbitrary data. 48 | # - Readability :: it is easy for someone to examine and understand the structure of an S-expression. 49 | # - Economy :: S-expressions represent data compactly. 50 | # - Tranportability :: S-expressions are easy to transport over communication media (such as email) with unusual encoding rules. 51 | # - Flexibility :: S-expressions make it relatively simple to modify and extend data structures. 52 | # - Canonicalization :: They produce a unique "canonical" form of an S-expression, for digital signature purposes. 53 | # - Efficiency :: S-expressions should admit in-memory representations that allow efficient processing. 54 | 55 | ** Configuration 56 | sexpr accepts numerous configuration 57 | 58 | *** Predefined Configurations 59 | | Name | ~square_brackets~ | ~semi_comment~ | ~colon_keywords~ | ~hex_escapes~ | ~pipe_action~ | Notes | 60 | |-------------+-------------------+----------------+------------------+---------------+----------------+---------------------------------------------------------------------| 61 | | =STANDARD= | ✓ | ✗ | ✓ | ✓ | Base64Interior | A generic 'standard' s-expression | 62 | | =SMTLIB= | ✗ | ✓ | ✓ | ✗ | QuoteInterior | A common interchange format for SAT and SMT solvers | 63 | | =KICAD= | ✓ | ✓ | ✓ | ✓ | None | A computer-aided design program | 64 | | =GUILE= | ✓ | ✓ | ✓ | ✓ | None | A scheme intended for embedding in existing C programs | 65 | | =CANONICAL= | ✗ | ✗ | ✗ | ✗ | None | A common, interchangable encoding for many cryptographic protocols. | 66 | 67 | 68 | *** Configuration Variables 69 | 70 | **** =semi_comment= 71 | Line comments can be enabled when parsing s-expressions by setting 72 | ~semi_comment = Some(&["#", ";"])~. 73 | 74 | This ignores the rest of the stream until encountering a newline or EOF, 75 | this does *not* comment out interior s-expressions like proposals like [[http://srfi.schemers.org/srfi-62/srfi-62.html][SRFI 76 | 62]]. 77 | 78 | ***** =colon_keywords= 79 | Many Scheme implementations assign a special meaning to atoms beginning with 80 | =#:= or =:=, sexpr can parse these as 'keywords' or they can be treated as valid 81 | starting characters to an ordinary symbol. =(item :keyword value :keyword2 value)= 82 | 83 | You can control this behaviour with ~ParseConfig.allow_keywords = Some(&["#", "#:"])~ 84 | 85 | ***** =square_brackets= 86 | Some Lisp implementations and s-expressions allow square brackets (=[= and 87 | =]=) to be used as an alternative bracket character. 88 | 89 | These brackets must still themselves remain matched. 90 | 91 | ***** =radix_escape= 92 | ****** ~#~ 93 | Libgcrypt, GPG and numerous Scheme implementations allow you to enclose a 94 | hexadecimal string in =#= characters: ~(q #61626364656667#)~ 95 | 96 | You can enable this with =hex_escapes= 97 | 98 | ****** ~#b~ and ~#x~ 99 | In a similar fashion, =#b= and =#x= are used to specify binary and 100 | hexadecimal encodings of the number that follows the trailing letter. 101 | 102 | ~((two-hundred-fifty-five #xff)~ would be encoded as =List(Symbol(two-hundred-fifty-five), U64(255))= 103 | Similarly, ~(sixteen #b10000))~ would be encoded as =List(Symbol(sixteen), U64(16))= 104 | 105 | You can control if both of these are accepted with the ~radix_escape~ option. 106 | 107 | ****** Both 108 | When both of these options are enabled in tandem, sexpr will use the 109 | following character to determine the variety of radix specification. 110 | 111 | ****** Neither 112 | If ~radix_escape~ is false, the initial ~#~ character will be treated as 113 | an atom. 114 | 115 | ***** =parse_pipe_behavior= 116 | Standard decoding treats the | character as a valid starting literal to any 117 | Atom, although two other options are permitted: 118 | 119 | ******* /Advanced/-style 120 | Rivest-style 'advanced' encodings dictate a string between two =|= 121 | characters be decoded as a stream of u8 (octets) in Base64. 122 | 123 | Use ~ParseConfig.pipe_action = ParsePipeBehavior::Base64Interior~ 124 | 125 | ******* SMTLIBv2 126 | SMT and SAT solvers using this format use the =|= character to quote it's 127 | interior, preserving line breaks and other whitespace in a Symbol. 128 | 129 | Use ~ParseConfig.pipe_action = ParsePipeBehavior::QuoteInterior~ 130 | ***** =transport= 131 | Today, sexpr supports the most common form of S-expression transport 132 | encoding, [[https://tools.ietf.org/html/rfc4648][RFC 4648 Base64]]. To indicate that you'd like to encode or decode 133 | an S-expression as Base64, you can modify your configuration as following. 134 | 135 | #+BEGIN_SRC rust 136 | let mut config = STANDARD.copy() 137 | mut.transport = TransportEncoding::Base64 138 | #+END_SRC 139 | 140 | If you'd like to add a new transport field, simple add to the 141 | TransportEncoding enum, and create a new trait that implements 142 | =SexpTransport=, the rest is handled for you. 143 | 144 | *** Encoding 145 | In a 2012 Dr. Dobb's retrospective, Karl Eiger noted that S-expressions are 146 | have been in continuous use longer than any other formats that remain in 147 | widespread use today. 148 | 149 | Despite this long history, there is no canonical way to encode a variety of 150 | different abstract data structures. 151 | 152 | **** Sequences 153 | #+BEGIN_SRC rust 154 | let vec: Vec = vec![1,2,3]; 155 | sexpr::encode(&vec) 156 | #+END_SRC 157 | Result: 158 | : (1 2 3) 159 | 160 | #+BEGIN_SRC rust 161 | let hs: HashSet = vec!(1, 2, 3).into_iter().collect(); 162 | sexpr::encode(&hs) 163 | #+END_SRC 164 | Result: 165 | : (1 2 3) 166 | 167 | **** Hash Tables 168 | #+BEGIN_SRC rust 169 | let ht = HashMap::new(); 170 | ht.insert('a', 1); 171 | ht.insert('b', 2); 172 | ht.insert('c', 3); 173 | sexpr::encode(&ht); 174 | #+END_SRC 175 | Result: 176 | : ((a . 1) (b . 2) (c . 3)) 177 | 178 | **** Tuple 179 | ***** Struct 180 | #+BEGIN_SRC rust 181 | struct TupleStruct(i32, i32, i32); 182 | let ts = TupleStruct(1, 2, 3); 183 | sexpr::encode(&ts); 184 | #+END_SRC 185 | Result: 186 | : ((_field0 1) (_field1 2) (_field2 3)) 187 | 188 | **** Struct 189 | ***** Ordinary 190 | #+BEGIN_SRC rust 191 | struct Color { 192 | r: u8, 193 | g: u8, 194 | b: u8, 195 | } 196 | sexpr::encode(&Color {r: 1, g: 2, b: 3}); 197 | sexpr::encode(&Color {r: 1, g: 2, b: 3}, (true)); 198 | #+END_SRC 199 | Result: 200 | : ((variant Color) ((r 1) (g 2) (b 3))) 201 | : ((r 1) (g 2) (b 3)) 202 | 203 | ***** Tuple Struct 204 | #+BEGIN_SRC rust 205 | struct Kangaroo(u32, String); 206 | sexpr::encode(&Kangaroo(34, &"William"); 207 | #+END_SRC 208 | Result: 209 | #+RESULTS: 210 | : (34 "William") 211 | 212 | ***** Newtype 213 | #+BEGIN_SRC rust 214 | struct Inches(u64) 215 | sexpr::encode(&Inches(128)); 216 | #+END_SRC 217 | Result 218 | : 128 219 | 220 | ***** Unit 221 | #+BEGIN_SRC rust 222 | struct Instance 223 | #+END_SRC 224 | Result: 225 | : nil 226 | 227 | **** Enum 228 | #+BEGIN_SRC rust 229 | enum E { 230 | W { a: i32, b: i32 }, 231 | X(i32, i32), 232 | Y(i32), 233 | Z, 234 | } 235 | 236 | E::W { a: 0, b: 0 }; 237 | E::X(0, 0); 238 | E::Y(0); 239 | E::Z; 240 | #+END_SRC 241 | Result: 242 | : ((variant W) ((a 0) (b 0))) 243 | : ((variant X) (0 0)) 244 | : ((variant Y) 0) 245 | : ((variant Z)) 246 | -------------------------------------------------------------------------------- /src/atom.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | use error::Error; 9 | use serde::de::{self, Visitor}; 10 | use serde::{Serialize, Serializer, Deserialize, Deserializer}; 11 | use std::fmt::{self, Debug, Display}; 12 | 13 | use std::borrow::Cow; 14 | 15 | /// Represents a Sexp atom, whether symbol, keyword or string. 16 | #[derive(Clone, PartialEq)] 17 | pub struct Atom { 18 | a: A 19 | } 20 | 21 | #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))] 22 | #[derive(Clone, Debug, PartialEq)] 23 | enum A { 24 | Symbol(String), 25 | Keyword(String), 26 | String(String) 27 | } 28 | 29 | impl Atom { 30 | pub fn is_symbol(&self) -> bool { 31 | match self.a { 32 | A::Symbol(_) => true, 33 | A::Keyword(_) => false, 34 | A::String(_) => false, 35 | } 36 | } 37 | 38 | pub fn is_keyword(&self) -> bool { 39 | match self.a { 40 | A::Symbol(_) => false, 41 | A::Keyword(_) => true, 42 | A::String(_) => false, 43 | } 44 | } 45 | 46 | pub fn is_string(&self) -> bool { 47 | match self.a { 48 | A::Symbol(_) => false, 49 | A::Keyword(_) => false, 50 | A::String(_) => true, 51 | } 52 | } 53 | 54 | pub fn into_string(s: String) -> Self { 55 | Atom { a: A::String(s) } 56 | } 57 | 58 | pub fn into_symbol(s: String) -> Self { 59 | Atom { a: A::Symbol(s) } 60 | } 61 | 62 | /// Returns an Atom appropriate for it's contents. 63 | /// 64 | /// Criteria for discriminating variants can be configured as appropriate. 65 | /// # Examples 66 | pub fn discriminate(s: String) -> Self { 67 | if s.starts_with("#:") { 68 | let (_, keyword) = s.split_at(2); 69 | Atom { a: A::Keyword(String::from(keyword)) } 70 | } else if (s.starts_with('"') && s.ends_with('"')) 71 | || (s.starts_with("'") && s.ends_with("'")) { 72 | Atom { a: A::String(String::from(&s[1..s.len()]))} 73 | } else { 74 | Atom { a: A::Symbol(s) } 75 | } 76 | } 77 | 78 | #[inline] 79 | pub fn from_str(s: &str) -> Self { 80 | Atom::discriminate(String::from(s)) 81 | } 82 | 83 | #[inline] 84 | pub fn from_string(s: String) -> Self { 85 | Atom::discriminate(s) 86 | } 87 | 88 | #[inline] 89 | pub fn as_str<'a>(&'a self) -> &'a str { 90 | match self.a { 91 | A::Symbol(ref s) => s, 92 | A::Keyword(ref s) => s, 93 | A::String(ref s) => s, 94 | } 95 | } 96 | 97 | #[inline] 98 | pub fn as_string(&self) -> String { 99 | let s = match self.a { 100 | A::Symbol(ref s) => s, 101 | A::Keyword(ref s) => s, 102 | A::String(ref s) => s, 103 | }; 104 | 105 | s.clone() 106 | } 107 | } 108 | 109 | impl fmt::Display for Atom { 110 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 111 | match self.a { 112 | A::Symbol(ref s) => Display::fmt(&s, formatter), 113 | A::Keyword(ref s) => Display::fmt(&s, formatter), 114 | A::String(ref s) => Display::fmt(&s, formatter), 115 | } 116 | } 117 | } 118 | 119 | impl Debug for Atom { 120 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 121 | Debug::fmt(&self.a, formatter) 122 | } 123 | } 124 | 125 | 126 | impl Serialize for Atom { 127 | #[inline] 128 | fn serialize(&self, serializer: S) -> Result 129 | where 130 | S: Serializer, 131 | { 132 | match self.a { 133 | A::Symbol(ref s) => serializer.serialize_newtype_struct("Symbol", s), 134 | A::Keyword(ref s) => serializer.serialize_str(s), 135 | A::String(ref s) => serializer.serialize_str(s), 136 | } 137 | } 138 | } 139 | 140 | impl<'de> Deserialize<'de> for Atom { 141 | #[inline] 142 | fn deserialize(deserializer: D) -> Result 143 | where 144 | D: Deserializer<'de>, 145 | { 146 | struct AtomVisitor; 147 | 148 | impl<'de> Visitor<'de> for AtomVisitor { 149 | type Value = Atom; 150 | 151 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 152 | formatter.write_str("an atom") 153 | } 154 | 155 | // #[inline] 156 | // fn visit_str(self, value: &str) -> Result 157 | // { 158 | // self.visit_string(String::from(value)) 159 | // } 160 | 161 | #[inline] 162 | fn visit_string(self, value: String) -> Result 163 | where 164 | E: de::Error, 165 | { 166 | Ok(Atom::from_string(value)) 167 | } 168 | } 169 | 170 | deserializer.deserialize_any(AtomVisitor) 171 | } 172 | } 173 | 174 | 175 | impl<'de> Deserializer<'de> for Atom { 176 | type Error = Error; 177 | 178 | #[inline] 179 | fn deserialize_any(self, visitor: V) -> Result 180 | where 181 | V: Visitor<'de>, 182 | { 183 | match self.a { 184 | A::Symbol(s) => visitor.visit_string(s), 185 | A::Keyword(s) => visitor.visit_string(s), 186 | A::String(s) => visitor.visit_string(s), 187 | } 188 | } 189 | 190 | forward_to_deserialize_any! { 191 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 192 | byte_buf option unit unit_struct newtype_struct seq tuple 193 | tuple_struct map struct enum identifier ignored_any 194 | } 195 | } 196 | 197 | 198 | impl<'de, 'a> Deserializer<'de> for &'a Atom { 199 | type Error = Error; 200 | 201 | #[inline] 202 | fn deserialize_any(self, visitor: V) -> Result 203 | where 204 | V: Visitor<'de>, 205 | { 206 | match self.a { 207 | A::Symbol(ref s) => visitor.visit_string(s.clone()), 208 | A::Keyword(ref s) => visitor.visit_string(s.clone()), 209 | A::String(ref s) => visitor.visit_string(s.clone()), 210 | } 211 | } 212 | 213 | forward_to_deserialize_any! { 214 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 215 | byte_buf option unit unit_struct newtype_struct seq tuple 216 | tuple_struct map struct enum identifier ignored_any 217 | } 218 | } 219 | 220 | impl From for Atom { 221 | #[inline] 222 | fn from(s: String) -> Self { 223 | Atom::from_string(String::from(s)) 224 | } 225 | } 226 | 227 | 228 | impl<'a> From<&'a str> for Atom { 229 | #[inline] 230 | fn from(s: &'a str) -> Self { 231 | Atom::from_str(s) 232 | } 233 | } 234 | 235 | impl<'a> From> for Atom { 236 | #[inline] 237 | fn from(s: Cow<'a, str>) -> Self { 238 | Atom::from_string(s.to_string()) 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! Deserialize S-expression data to a Rust data structure. 10 | 11 | use std::{i32, u64}; 12 | use std::io; 13 | use std::marker::PhantomData; 14 | 15 | use serde::de::{self, Unexpected}; 16 | 17 | use super::error::{Error, ErrorCode, Result}; 18 | 19 | use read::{self, Reference}; 20 | 21 | pub use read::{Read, IoRead, SliceRead, StrRead}; 22 | use atom::Atom; 23 | use sexp::Sexp; 24 | 25 | 26 | ////////////////////////////////////////////////////////////////////////////// 27 | 28 | /// A structure that deserializes S-expressions into Rust values. 29 | pub struct Deserializer { 30 | read: R, 31 | str_buf: Vec, 32 | remaining_depth: u8, 33 | } 34 | 35 | impl<'de, R> Deserializer 36 | where 37 | R: read::Read<'de>, 38 | { 39 | /// Create a S-expression deserializer from one of the possible sexpr input 40 | /// sources. 41 | /// 42 | /// Typically it is more convenient to use one of these methods instead: 43 | /// 44 | /// - Deserializer::from_str 45 | /// - Deserializer::from_bytes 46 | /// - Deserializer::from_reader 47 | pub fn new(read: R) -> Self { 48 | Deserializer { 49 | read: read, 50 | str_buf: Vec::with_capacity(128), 51 | remaining_depth: 128, 52 | } 53 | } 54 | } 55 | 56 | impl Deserializer> 57 | where 58 | R: io::Read, 59 | { 60 | /// Creates a S-expression deserializer from an `io::Read`. 61 | pub fn from_reader(reader: R) -> Self { 62 | Deserializer::new(read::IoRead::new(reader)) 63 | } 64 | } 65 | 66 | impl<'a> Deserializer> { 67 | /// Creates a S-expression deserializer from a `&[u8]`. 68 | pub fn from_slice(bytes: &'a [u8]) -> Self { 69 | Deserializer::new(read::SliceRead::new(bytes)) 70 | } 71 | } 72 | 73 | impl<'a> Deserializer> { 74 | /// Creates a S-expression deserializer from a `&str`. 75 | pub fn from_str(s: &'a str) -> Self { 76 | Deserializer::new(read::StrRead::new(s)) 77 | } 78 | } 79 | 80 | macro_rules! overflow { 81 | ($a:ident * 10 + $b:ident, $c:expr) => { 82 | $a >= $c / 10 && ($a > $c / 10 || $b > $c % 10) 83 | } 84 | } 85 | 86 | enum Number { 87 | F64(f64), 88 | U64(u64), 89 | I64(i64), 90 | } 91 | 92 | impl Number { 93 | fn visit<'de, V>(self, visitor: V) -> Result 94 | where 95 | V: de::Visitor<'de>, 96 | { 97 | match self { 98 | Number::F64(x) => visitor.visit_f64(x), 99 | Number::U64(x) => visitor.visit_u64(x), 100 | Number::I64(x) => visitor.visit_i64(x), 101 | } 102 | } 103 | } 104 | 105 | impl<'de, R: Read<'de>> Deserializer { 106 | /// The `Deserializer::end` method should be called after a value has been fully deserialized. 107 | /// This allows the `Deserializer` to validate that the input stream is at the end or that it 108 | /// only has trailing whitespace. 109 | pub fn end(&mut self) -> Result<()> { 110 | match try!(self.parse_whitespace()) { 111 | Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), 112 | None => Ok(()), 113 | } 114 | } 115 | 116 | /// Turn a Sexp deserializer into an iterator over values of type T. 117 | pub fn into_iter(self) -> StreamDeserializer<'de, R, T> 118 | where 119 | T: de::Deserialize<'de>, 120 | { 121 | // This cannot be an implementation of std::iter::IntoIterator because 122 | // we need the caller to choose what T is. 123 | let offset = self.read.byte_offset(); 124 | StreamDeserializer { 125 | de: self, 126 | offset: offset, 127 | output: PhantomData, 128 | lifetime: PhantomData, 129 | } 130 | } 131 | 132 | fn peek(&mut self) -> Result> { 133 | self.read.peek().map_err(Error::io) 134 | } 135 | 136 | fn peek_or_null(&mut self) -> Result { 137 | Ok(try!(self.peek()).unwrap_or(b'\x00')) 138 | } 139 | 140 | fn eat_char(&mut self) { 141 | self.read.discard(); 142 | } 143 | 144 | fn next_char(&mut self) -> Result> { 145 | self.read.next().map_err(Error::io) 146 | } 147 | 148 | fn next_char_or_null(&mut self) -> Result { 149 | Ok(try!(self.next_char()).unwrap_or(b'\x00')) 150 | } 151 | 152 | /// Error caused by a byte from next_char(). 153 | fn error(&mut self, reason: ErrorCode) -> Error { 154 | let pos = self.read.position(); 155 | Error::syntax(reason, pos.line, pos.column) 156 | } 157 | 158 | /// Error caused by a byte from peek(). 159 | fn peek_error(&mut self, reason: ErrorCode) -> Error { 160 | let pos = self.read.peek_position(); 161 | Error::syntax(reason, pos.line, pos.column) 162 | } 163 | 164 | /// Returns the first non-whitespace byte without consuming it, or `None` if 165 | /// EOF is encountered. 166 | fn parse_whitespace(&mut self) -> Result> { 167 | loop { 168 | match try!(self.peek()) { 169 | Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => { 170 | self.eat_char(); 171 | } 172 | other => { 173 | return Ok(other); 174 | } 175 | } 176 | } 177 | } 178 | 179 | fn parse_value(&mut self, visitor: V) -> Result 180 | where 181 | V: de::Visitor<'de>, 182 | { 183 | let peek = match try!(self.parse_whitespace()) { 184 | Some(b) => b, 185 | None => { 186 | return Err(self.peek_error(ErrorCode::EofWhileParsingValue)); 187 | } 188 | }; 189 | 190 | let value = match peek { 191 | b'#' => { 192 | self.eat_char(); 193 | match try!(self.next_char()) { 194 | Some(b't') => visitor.visit_bool(true), 195 | Some(b'f') => visitor.visit_bool(false), 196 | Some(b'n') => { 197 | try!(self.parse_ident(b"il")); 198 | visitor.visit_bool(true) 199 | }, 200 | Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeIdent)), 201 | None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)) 202 | } 203 | } 204 | b'-' => { 205 | self.eat_char(); 206 | try!(self.parse_integer(false)).visit(visitor) 207 | } 208 | b'0'...b'9' => try!(self.parse_integer(true)).visit(visitor), 209 | b'"' => { 210 | self.eat_char(); 211 | self.str_buf.clear(); 212 | match try!(self.read.parse_str(&mut self.str_buf)) { 213 | Reference::Borrowed(s) => visitor.visit_borrowed_str(s), 214 | Reference::Copied(s) => visitor.visit_str(s), 215 | } 216 | } 217 | b'(' => { 218 | self.remaining_depth -= 1; 219 | if self.remaining_depth == 0 { 220 | return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); 221 | } 222 | 223 | self.eat_char(); 224 | let ret = visitor.visit_seq(SeqAccess::new(self)); 225 | 226 | self.remaining_depth += 1; 227 | 228 | try!(self.parse_whitespace()); 229 | 230 | match (ret, self.end_seq()) { 231 | (Ok(ret), Ok(())) => Ok(ret), 232 | (Err(err), _) | (_, Err(err)) => Err(err), 233 | } 234 | } 235 | b'a' ... b'z' | b'A' ... b'Z' => { 236 | self.str_buf.clear(); 237 | match try!(self.read.parse_symbol(&mut self.str_buf)) { 238 | Reference::Borrowed(s) => visitor.visit_newtype_struct(Atom::from_str(s)), 239 | Reference::Copied(s) => visitor.visit_newtype_struct(Atom::from_str(s)), 240 | } 241 | } 242 | _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), 243 | }; 244 | 245 | match value { 246 | Ok(value) => Ok(value), 247 | // The de::Error and From impls both create errors 248 | // with unknown line and column. Fill in the position here by 249 | // looking at the current index in the input. There is no way to 250 | // tell whether this should call `error` or `peek_error` so pick the 251 | // one that seems correct more often. Worst case, the position is 252 | // off by one character. 253 | Err(err) => Err(err.fix_position(|code| self.error(code))), 254 | } 255 | } 256 | 257 | fn parse_ident(&mut self, ident: &[u8]) -> Result<()> { 258 | for c in ident { 259 | if Some(*c) != try!(self.next_char()) { 260 | return Err(self.error(ErrorCode::ExpectedSomeIdent)); 261 | } 262 | } 263 | 264 | Ok(()) 265 | } 266 | 267 | fn parse_integer(&mut self, pos: bool) -> Result { 268 | match try!(self.next_char_or_null()) { 269 | b'0' => { 270 | // There can be only one leading '0'. 271 | match try!(self.peek_or_null()) { 272 | b'0'...b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)), 273 | _ => self.parse_number(pos, 0), 274 | } 275 | } 276 | c @ b'1'...b'9' => { 277 | let mut res = (c - b'0') as u64; 278 | 279 | loop { 280 | match try!(self.peek_or_null()) { 281 | c @ b'0'...b'9' => { 282 | self.eat_char(); 283 | let digit = (c - b'0') as u64; 284 | 285 | // We need to be careful with overflow. If we can, try to keep the 286 | // number as a `u64` until we grow too large. At that point, switch to 287 | // parsing the value as a `f64`. 288 | if overflow!(res * 10 + digit, u64::MAX) { 289 | return Ok(Number::F64(try!(self.parse_long_integer( 290 | pos, 291 | res, 292 | 1, // res * 10^1 293 | )))); 294 | } 295 | 296 | res = res * 10 + digit; 297 | } 298 | _ => { 299 | return self.parse_number(pos, res); 300 | } 301 | } 302 | } 303 | } 304 | _ => Err(self.error(ErrorCode::InvalidNumber)), 305 | } 306 | } 307 | 308 | fn parse_long_integer( 309 | &mut self, 310 | pos: bool, 311 | significand: u64, 312 | mut exponent: i32, 313 | ) -> Result { 314 | loop { 315 | match try!(self.peek_or_null()) { 316 | b'0'...b'9' => { 317 | self.eat_char(); 318 | // This could overflow... if your integer is gigabytes long. 319 | // Ignore that possibility. 320 | exponent += 1; 321 | } 322 | b'.' => { 323 | return self.parse_decimal(pos, significand, exponent); 324 | } 325 | // b'e' | b'E' => { 326 | // return self.parse_exponent(pos, significand, exponent); 327 | // } 328 | _ => { 329 | return self.f64_from_parts(pos, significand, exponent); 330 | } 331 | } 332 | } 333 | } 334 | 335 | fn parse_number(&mut self, pos: bool, significand: u64) -> Result { 336 | Ok(match try!(self.peek_or_null()) { 337 | b'.' => Number::F64(try!(self.parse_decimal(pos, significand, 0))), 338 | // b'e' | b'E' => Number::F64(try!(self.parse_exponent(pos, significand, 0))), 339 | _ => { 340 | if pos { 341 | Number::U64(significand) 342 | } else { 343 | let neg = (significand as i64).wrapping_neg(); 344 | 345 | // Convert into a float if we underflow. 346 | if neg > 0 { 347 | Number::F64(-(significand as f64)) 348 | } else { 349 | Number::I64(neg) 350 | } 351 | } 352 | } 353 | }) 354 | } 355 | 356 | 357 | fn parse_decimal( 358 | &mut self, 359 | pos: bool, 360 | mut significand: u64, 361 | mut exponent: i32, 362 | ) -> Result { 363 | self.eat_char(); 364 | 365 | let mut at_least_one_digit = false; 366 | while let c @ b'0'...b'9' = try!(self.peek_or_null()) { 367 | self.eat_char(); 368 | let digit = (c - b'0') as u64; 369 | at_least_one_digit = true; 370 | 371 | if overflow!(significand * 10 + digit, u64::MAX) { 372 | // The next multiply/add would overflow, so just ignore all 373 | // further digits. 374 | while let b'0'...b'9' = try!(self.peek_or_null()) { 375 | self.eat_char(); 376 | } 377 | break; 378 | } 379 | 380 | significand = significand * 10 + digit; 381 | exponent -= 1; 382 | } 383 | 384 | if !at_least_one_digit { 385 | return Err(self.peek_error(ErrorCode::InvalidNumber)); 386 | } 387 | 388 | match try!(self.peek_or_null()) { 389 | // b'e' | b'E' => self.parse_exponent(pos, significand, exponent), 390 | _ => self.f64_from_parts(pos, significand, exponent), 391 | } 392 | } 393 | 394 | fn f64_from_parts( 395 | &mut self, 396 | pos: bool, 397 | significand: u64, 398 | mut exponent: i32, 399 | ) -> Result { 400 | let mut f = significand as f64; 401 | loop { 402 | match POW10.get(exponent.abs() as usize) { 403 | Some(&pow) => { 404 | if exponent >= 0 { 405 | f *= pow; 406 | if f.is_infinite() { 407 | return Err(self.error(ErrorCode::NumberOutOfRange)); 408 | } 409 | } else { 410 | f /= pow; 411 | } 412 | break; 413 | } 414 | None => { 415 | if f == 0.0 { 416 | break; 417 | } 418 | if exponent >= 0 { 419 | return Err(self.error(ErrorCode::NumberOutOfRange)); 420 | } 421 | f /= 1e308; 422 | exponent += 308; 423 | } 424 | } 425 | } 426 | Ok(if pos { f } else { -f }) 427 | } 428 | 429 | fn end_seq(&mut self) -> Result<()> { 430 | match try!(self.parse_whitespace()) { 431 | Some(b')') => { 432 | self.eat_char(); 433 | Ok(()) 434 | } 435 | Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)), 436 | None => Err(self.peek_error(ErrorCode::EofWhileParsingList)), 437 | } 438 | } 439 | } 440 | 441 | #[cfg_attr(rustfmt, rustfmt_skip)] 442 | static POW10: [f64; 309] = 443 | [1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, 444 | 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019, 445 | 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029, 446 | 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039, 447 | 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049, 448 | 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059, 449 | 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069, 450 | 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079, 451 | 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089, 452 | 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099, 453 | 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, 454 | 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, 455 | 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, 456 | 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, 457 | 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, 458 | 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, 459 | 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, 460 | 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, 461 | 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, 462 | 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, 463 | 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, 464 | 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, 465 | 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, 466 | 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, 467 | 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, 468 | 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, 469 | 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, 470 | 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, 471 | 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, 472 | 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, 473 | 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308]; 474 | 475 | 476 | impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer { 477 | type Error = Error; 478 | 479 | #[inline] 480 | fn deserialize_any(self, visitor: V) -> Result 481 | where 482 | V: de::Visitor<'de>, 483 | { 484 | self.parse_value(visitor) 485 | } 486 | 487 | /// Parses a `nil` as a None, and any other values as a `Some(...)`. 488 | #[inline] 489 | fn deserialize_option(self, visitor: V) -> Result 490 | where 491 | V: de::Visitor<'de>, 492 | { 493 | match try!(self.parse_whitespace()) { 494 | Some(b'n') => { 495 | self.eat_char(); 496 | try!(self.parse_ident(b"il")); 497 | visitor.visit_none() 498 | } 499 | _ => visitor.visit_some(self), 500 | } 501 | } 502 | 503 | /// Parses a newtype struct as the underlying value. 504 | #[inline] 505 | fn deserialize_newtype_struct(self, _name: &str, visitor: V) -> Result 506 | where 507 | V: de::Visitor<'de>, 508 | { 509 | visitor.visit_newtype_struct(self) 510 | } 511 | 512 | /// Parses an enum as an s-expression like `(($KEY1 $VALUE1) ($KEY2 $VALUE2))` where $VALUE 513 | /// is either a direct Sexp or a sequence. 514 | #[inline] 515 | fn deserialize_enum( 516 | self, 517 | _name: &str, 518 | _variants: &'static [&'static str], 519 | visitor: V, 520 | ) -> Result 521 | where 522 | V: de::Visitor<'de>, 523 | { 524 | match try!(self.parse_whitespace()) { 525 | Some(b'(') => { 526 | self.remaining_depth -= 1; 527 | if self.remaining_depth == 0 { 528 | return Err(self.peek_error(ErrorCode::RecursionLimitExceeded)); 529 | } 530 | 531 | self.eat_char(); 532 | let value = try!(visitor.visit_enum(VariantAccess::new(self))); 533 | 534 | self.remaining_depth += 1; 535 | 536 | match try!(self.parse_whitespace()) { 537 | Some(b')') => { 538 | self.eat_char(); 539 | Ok(value) 540 | } 541 | Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)), 542 | None => Err(self.error(ErrorCode::EofWhileParsingAlist)), 543 | } 544 | } 545 | Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)), 546 | // TODO: ATOMS BROKEN 547 | Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)), 548 | None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)), 549 | } 550 | } 551 | 552 | 553 | fn deserialize_bytes(self, visitor: V) -> Result 554 | where 555 | V: de::Visitor<'de>, 556 | { 557 | match try!(self.parse_whitespace()) { 558 | Some(b'"') => { 559 | self.eat_char(); 560 | self.str_buf.clear(); 561 | match try!(self.read.parse_str_raw(&mut self.str_buf)) { 562 | Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b), 563 | Reference::Copied(b) => visitor.visit_bytes(b), 564 | } 565 | } 566 | _ => self.deserialize_any(visitor), 567 | } 568 | 569 | } 570 | 571 | #[inline] 572 | fn deserialize_byte_buf(self, visitor: V) -> Result 573 | where 574 | V: de::Visitor<'de>, 575 | { 576 | self.deserialize_bytes(visitor) 577 | } 578 | 579 | forward_to_deserialize_any! { 580 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string unit 581 | unit_struct seq tuple tuple_struct map struct identifier ignored_any 582 | } 583 | 584 | } 585 | 586 | // POSSIBLY BROKEN -------------------------------------------------------- 587 | struct SeqAccess<'a, R: 'a> { 588 | de: &'a mut Deserializer, 589 | first: bool, 590 | } 591 | 592 | impl<'a, R: 'a> SeqAccess<'a, R> { 593 | fn new(de: &'a mut Deserializer) -> Self { 594 | SeqAccess { 595 | de: de, 596 | first: true, 597 | } 598 | } 599 | } 600 | 601 | impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { 602 | type Error = Error; 603 | 604 | fn next_element_seed(&mut self, seed: T) -> Result> 605 | where 606 | T: de::DeserializeSeed<'de>, 607 | { 608 | match try!(self.de.peek()) { 609 | Some(b')') => { 610 | return Ok(None); 611 | }, 612 | Some(b' ') => { 613 | self.de.eat_char(); 614 | } 615 | Some(_) => { 616 | try!(self.de.parse_whitespace()); 617 | if self.first { 618 | self.first = false; 619 | } else { 620 | return Err(self.de.peek_error(ErrorCode::ExpectedListEltOrEnd)); 621 | } 622 | }, 623 | None => { 624 | return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); 625 | } 626 | } 627 | 628 | if try!(self.de.peek()).unwrap() == b')' { 629 | Ok(None) 630 | } else { 631 | seed.deserialize(&mut *self.de).map(Some) 632 | } 633 | } 634 | } 635 | 636 | // END POSSIBLY BROKEN -------------------------------------------------------- 637 | 638 | struct VariantAccess<'a, R: 'a> { 639 | de: &'a mut Deserializer, 640 | } 641 | 642 | impl<'a, R: 'a> VariantAccess<'a, R> { 643 | fn new(de: &'a mut Deserializer) -> Self { 644 | VariantAccess { de: de } 645 | } 646 | } 647 | 648 | impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for VariantAccess<'a, R> { 649 | type Error = Error; 650 | type Variant = Self; 651 | 652 | fn variant_seed(self, _seed: V) -> Result<(V::Value, Self)> 653 | where 654 | V: de::DeserializeSeed<'de>, 655 | { 656 | unimplemented!() 657 | } 658 | } 659 | 660 | impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for VariantAccess<'a, R> { 661 | type Error = Error; 662 | 663 | fn unit_variant(self) -> Result<()> { 664 | de::Deserialize::deserialize(self.de) 665 | } 666 | 667 | fn newtype_variant_seed(self, seed: T) -> Result 668 | where 669 | T: de::DeserializeSeed<'de>, 670 | { 671 | seed.deserialize(self.de) 672 | } 673 | 674 | fn tuple_variant(self, _len: usize, visitor: V) -> Result 675 | where 676 | V: de::Visitor<'de>, 677 | { 678 | de::Deserializer::deserialize_any(self.de, visitor) 679 | } 680 | 681 | fn struct_variant(self, _fields: &'static [&'static str], visitor: V) -> Result 682 | where 683 | V: de::Visitor<'de>, 684 | { 685 | de::Deserializer::deserialize_any(self.de, visitor) 686 | } 687 | } 688 | 689 | struct UnitVariantAccess<'a, R: 'a> { 690 | de: &'a mut Deserializer, 691 | } 692 | 693 | impl<'a, R: 'a> UnitVariantAccess<'a, R> { 694 | fn new(de: &'a mut Deserializer) -> Self { 695 | UnitVariantAccess { de: de } 696 | } 697 | } 698 | 699 | impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, R> { 700 | type Error = Error; 701 | type Variant = Self; 702 | 703 | fn variant_seed(self, seed: V) -> Result<(V::Value, Self)> 704 | where 705 | V: de::DeserializeSeed<'de>, 706 | { 707 | let variant = try!(seed.deserialize(&mut *self.de)); 708 | Ok((variant, self)) 709 | } 710 | } 711 | 712 | impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, R> { 713 | type Error = Error; 714 | 715 | fn unit_variant(self) -> Result<()> { 716 | Ok(()) 717 | } 718 | 719 | fn newtype_variant_seed(self, _seed: T) -> Result 720 | where 721 | T: de::DeserializeSeed<'de>, 722 | { 723 | Err(de::Error::invalid_type(Unexpected::UnitVariant, &"newtype variant"),) 724 | } 725 | 726 | fn tuple_variant(self, _len: usize, _visitor: V) -> Result 727 | where 728 | V: de::Visitor<'de>, 729 | { 730 | Err(de::Error::invalid_type(Unexpected::UnitVariant, &"tuple variant"),) 731 | } 732 | 733 | fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result 734 | where 735 | V: de::Visitor<'de>, 736 | { 737 | Err(de::Error::invalid_type(Unexpected::UnitVariant, &"struct variant"),) 738 | } 739 | } 740 | 741 | macro_rules! deserialize_integer_key { 742 | ($deserialize:ident => $visit:ident) => { 743 | fn $deserialize(self, visitor: V) -> Result 744 | where 745 | V: de::Visitor<'de>, 746 | { 747 | self.de.eat_char(); 748 | self.de.str_buf.clear(); 749 | let string = try!(self.de.read.parse_str(&mut self.de.str_buf)); 750 | match (string.parse(), string) { 751 | (Ok(integer), _) => visitor.$visit(integer), 752 | (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s), 753 | (Err(_), Reference::Copied(s)) => visitor.visit_str(s), 754 | } 755 | } 756 | } 757 | } 758 | 759 | ////////////////////////////////////////////////////////////////////////////// 760 | 761 | /// Iterator that deserializes a stream into multiple Sexp values. 762 | /// 763 | /// A stream deserializer can be created from any SExp deserializer using the 764 | /// `Deserializer::into_iter` method. 765 | /// 766 | /// The data must consist of Sexp lists optionally separated by whitespace. A 767 | /// null, boolean, number, or string at the top level are all 768 | /// errors. 769 | /// 770 | /// ```rust,ignore 771 | /// extern crate sexpr; 772 | /// 773 | /// use sexpr::{Deserializer, Sexp}; 774 | /// 775 | /// fn main() { 776 | /// let data = "(a 1) () (1 2 3)"; 777 | /// 778 | /// let stream = Deserializer::from_str(data).into_iter::(); 779 | /// 780 | /// for value in stream { 781 | /// println!("{}", value.unwrap()); 782 | /// } 783 | /// } 784 | /// ``` 785 | pub struct StreamDeserializer<'de, R, T> { 786 | de: Deserializer, 787 | offset: usize, 788 | output: PhantomData, 789 | lifetime: PhantomData<&'de ()>, 790 | } 791 | 792 | impl<'de, R, T> StreamDeserializer<'de, R, T> 793 | where 794 | R: read::Read<'de>, 795 | T: de::Deserialize<'de>, 796 | { 797 | /// Create a sexp-stream deserializer from one of the possible sexpr 798 | /// input sources. 799 | /// 800 | /// Typically it is more convenient to use one of these methods instead: 801 | /// 802 | /// - Deserializer::from_str(...).into_iter() 803 | /// - Deserializer::from_bytes(...).into_iter() 804 | /// - Deserializer::from_reader(...).into_iter() 805 | pub fn new(read: R) -> Self { 806 | let offset = read.byte_offset(); 807 | StreamDeserializer { 808 | de: Deserializer::new(read), 809 | offset: offset, 810 | output: PhantomData, 811 | lifetime: PhantomData, 812 | } 813 | } 814 | 815 | /// Returns the number of bytes so far deserialized into a successful `T`. 816 | /// 817 | /// If a stream deserializer returns an EOF error, new data can be joined to 818 | /// `old_data[stream.byte_offset()..]` to try again. 819 | pub fn byte_offset(&self) -> usize { 820 | self.offset 821 | } 822 | } 823 | 824 | 825 | impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T> 826 | where 827 | R: Read<'de>, 828 | T: de::Deserialize<'de>, 829 | { 830 | type Item = Result; 831 | 832 | fn next(&mut self) -> Option> { 833 | // skip whitespaces, if any 834 | // this helps with trailing whitespaces, since whitespaces between 835 | // values are handled for us. 836 | match self.de.parse_whitespace() { 837 | Ok(None) => { 838 | self.offset = self.de.read.byte_offset(); 839 | None 840 | } 841 | Ok(Some(b'(')) => { 842 | self.offset = self.de.read.byte_offset(); 843 | let result = de::Deserialize::deserialize(&mut self.de); 844 | if result.is_ok() { 845 | self.offset = self.de.read.byte_offset(); 846 | } 847 | Some(result) 848 | } 849 | Ok(Some(_)) => Some(Err(self.de.peek_error(ErrorCode::ExpectedList))), 850 | Err(e) => Some(Err(e)), 851 | } 852 | } 853 | } 854 | 855 | ////////////////////////////////////////////////////////////////////////////// 856 | 857 | fn from_trait<'de, R, T>(read: R) -> Result 858 | where 859 | R: Read<'de>, 860 | T: de::Deserialize<'de>, 861 | { 862 | let mut de = Deserializer::new(read); 863 | let value = try!(de::Deserialize::deserialize(&mut de)); 864 | 865 | // Make sure the whole stream has been consumed. 866 | try!(de.end()); 867 | Ok(value) 868 | } 869 | 870 | /// Deserialize an instance of type `T` from an IO stream of S-expressions. 871 | /// 872 | /// # Errors 873 | /// 874 | /// This conversion can fail if the structure of the input does not match the 875 | /// structure expected by `T`, for example if `T` is a struct type but the input 876 | /// contains something other than a Sexp map. It can also fail if the structure 877 | /// is correct but `T`'s implementation of `Deserialize` decides that something 878 | /// is wrong with the data, for example required struct fields are missing from 879 | /// the Sexp map or some number is too big to fit in the expected primitive 880 | /// type. 881 | /// 882 | /// ```rust,ignore 883 | /// #[macro_use] 884 | /// extern crate serde_derive; 885 | /// 886 | /// extern crate serde; 887 | /// extern crate sexpr; 888 | /// 889 | /// use std::error::Error; 890 | /// use std::fs::File; 891 | /// use std::path::Path; 892 | /// 893 | /// #[derive(Deserialize, Debug)] 894 | /// struct User { 895 | /// fingerprint: String, 896 | /// location: String, 897 | /// } 898 | /// 899 | /// fn read_user_from_file>(path: P) -> Result> { 900 | /// // Open the file in read-only mode. 901 | /// let file = File::open(path)?; 902 | /// 903 | /// // Read the Sexp contents of the file as an instance of `User`. 904 | /// let u = sexpr::from_reader(file)?; 905 | /// 906 | /// // Return the `User`. 907 | /// Ok(u) 908 | /// } 909 | /// 910 | /// fn main() { 911 | /// # } 912 | /// # fn fake_main() { 913 | /// let u = read_user_from_file("test.scm").unwrap(); 914 | /// println!("{:#?}", u); 915 | /// } 916 | /// ``` 917 | pub fn from_reader(rdr: R) -> Result 918 | where 919 | R: io::Read, 920 | T: de::DeserializeOwned, 921 | { 922 | from_trait(read::IoRead::new(rdr)) 923 | } 924 | 925 | /// Deserialize an instance of type `T` from bytes of an S-expression. 926 | /// 927 | /// # Errors 928 | /// 929 | /// This conversion can fail if the structure of the input does not match the 930 | /// structure expected by `T`, for example if `T` is a struct type but the input 931 | /// contains something other than a S-expression "map". It can also fail if the 932 | /// structure is correct but `T`'s implementation of `Deserialize` decides that 933 | /// something is wrong with the data, for example required struct fields are 934 | /// missing from the S-expression or some number is too big to fit in the expected 935 | /// primitive type. 936 | /// 937 | /// ```rust,ignore 938 | /// #[macro_use] 939 | /// extern crate serde_derive; 940 | /// 941 | /// extern crate serde; 942 | /// extern crate sexpr; 943 | /// 944 | /// #[derive(Deserialize, Debug)] 945 | /// struct User { 946 | /// fingerprint: String, 947 | /// location: String, 948 | /// } 949 | /// 950 | /// fn main() { 951 | /// // The type of `s` is `&[u8]` 952 | /// let s = b"( 953 | /// (fingerprint \"0xF9BA143B95FF6D82\") 954 | /// (location \"Menlo Park, CA\") 955 | /// )"; 956 | /// 957 | /// let u: User = sexpr::from_slice(s).unwrap(); 958 | /// println!("{:#?}", u); 959 | /// } 960 | /// ``` 961 | pub fn from_slice<'a, T>(v: &'a [u8]) -> Result 962 | where 963 | T: de::Deserialize<'a>, 964 | { 965 | from_trait(read::SliceRead::new(v)) 966 | } 967 | 968 | /// Deserialize an instance of type `T` from a string of S-expressions. 969 | /// 970 | /// # Errors 971 | /// 972 | /// This conversion can fail if the structure of the input does not match the 973 | /// structure expected by `T`, for example if `T` is a struct type but the input 974 | /// contains something other than a S-expression "map". It can also fail if the 975 | /// structure is correct but `T`'s implementation of `Deserialize` decides that 976 | /// something is wrong with the data, for example required struct fields are 977 | /// missing from the S-expression or some number is too big to fit in the expected 978 | /// primitive type. 979 | /// 980 | /// ```rust,ignore 981 | /// #[macro_use] 982 | /// extern crate serde_derive; 983 | /// 984 | /// extern crate serde; 985 | /// extern crate sexpr; 986 | /// 987 | /// #[derive(Deserialize, Debug)] 988 | /// struct User { 989 | /// fingerprint: String, 990 | /// location: String, 991 | /// } 992 | /// 993 | /// fn main() { 994 | /// // The type of `s` is `&str` 995 | /// let s = "( 996 | /// (fingerprint . \"0xF9BA143B95FF6D82\") 997 | /// (location . \"Menlo Park, CA\") 998 | /// )"; 999 | /// 1000 | /// let u: User = sexpr::from_str(s).unwrap(); 1001 | /// println!("{:#?}", u); 1002 | /// } 1003 | /// ``` 1004 | pub fn from_str<'a, T>(s: &'a str) -> Result 1005 | where 1006 | T: de::Deserialize<'a>, 1007 | { 1008 | from_trait(read::StrRead::new(s)) 1009 | } 1010 | -------------------------------------------------------------------------------- /src/error.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! When serializing or deserializing S-expression goes wrong. 10 | 11 | use std::error; 12 | use std::fmt::{self, Debug, Display}; 13 | use std::io; 14 | use std::result; 15 | 16 | use serde::de; 17 | use serde::ser; 18 | 19 | /// This type represents all possible errors that can occur when serializing or 20 | /// deserializing S-expression data. 21 | pub struct Error { 22 | /// This `Box` allows us to keep the size of `Error` as small as possible. A 23 | /// larger `Error` type was substantially slower due to all the functions 24 | /// that pass around `Result`. 25 | err: Box, 26 | } 27 | 28 | /// Alias for a `Result` with the error type `sexpr::Error`. 29 | pub type Result = result::Result; 30 | 31 | impl Error { 32 | /// One-based line number at which the error was detected. 33 | /// 34 | /// Characters in the first line of the input (before the first newline 35 | /// character) are in line 1. 36 | pub fn line(&self) -> usize { 37 | self.err.line 38 | } 39 | 40 | /// One-based column number at which the error was detected. 41 | /// 42 | /// The first character in the input and any characters immediately 43 | /// following a newline character are in column 1. 44 | /// 45 | /// Note that errors may occur in column 0, for example if a read from an IO 46 | /// stream fails immediately following a previously read newline character. 47 | pub fn column(&self) -> usize { 48 | self.err.column 49 | } 50 | 51 | /// Categorizes the cause of this error. 52 | /// 53 | /// - `Category::Io` - failure to read or write bytes on an IO stream 54 | /// - `Category::Syntax` - input that is not syntactically valid S-expression 55 | /// - `Category::Data` - input data that is semantically incorrect 56 | /// - `Category::Eof` - unexpected end of the input data 57 | pub fn classify(&self) -> Category { 58 | match self.err.code { 59 | ErrorCode::Message(_) => Category::Data, 60 | ErrorCode::Io(_) => Category::Io, 61 | ErrorCode::EofWhileParsingList | 62 | ErrorCode::EofWhileParsingAlist | 63 | ErrorCode::EofWhileParsingString | 64 | ErrorCode::EofWhileParsingValue => Category::Eof, 65 | ErrorCode::ExpectedPairDot | 66 | ErrorCode::ExpectedListEltOrEnd | 67 | ErrorCode::ExpectedPairOrEnd | 68 | ErrorCode::ExpectedList | 69 | ErrorCode::ExpectedSomeIdent | 70 | ErrorCode::ExpectedSomeValue | 71 | ErrorCode::ExpectedSomeString | 72 | ErrorCode::InvalidEscape | 73 | ErrorCode::InvalidNumber | 74 | ErrorCode::NumberOutOfRange | 75 | ErrorCode::InvalidUnicodeCodePoint | 76 | ErrorCode::KeyMustBeAString | 77 | ErrorCode::LoneLeadingSurrogateInHexEscape | 78 | ErrorCode::TrailingCharacters | 79 | ErrorCode::UnexpectedEndOfHexEscape | 80 | ErrorCode::RecursionLimitExceeded => Category::Syntax, 81 | } 82 | } 83 | 84 | /// Returns true if this error was caused by a failure to read or write 85 | /// bytes on an IO stream. 86 | pub fn is_io(&self) -> bool { 87 | self.classify() == Category::Io 88 | } 89 | 90 | /// Returns true if this error was caused by input that was not 91 | /// syntactically valid S-expression. 92 | pub fn is_syntax(&self) -> bool { 93 | self.classify() == Category::Syntax 94 | } 95 | 96 | /// Returns true if this error was caused by input data that was 97 | /// semantically incorrect. 98 | /// 99 | /// For example, S-expression containing a number is semantically incorrect when the 100 | /// type being deserialized into holds a String. 101 | pub fn is_data(&self) -> bool { 102 | self.classify() == Category::Data 103 | } 104 | 105 | /// Returns true if this error was caused by prematurely reaching the end of 106 | /// the input data. 107 | /// 108 | /// Callers that process streaming input may be interested in retrying the 109 | /// deserialization once more data is available. 110 | pub fn is_eof(&self) -> bool { 111 | self.classify() == Category::Eof 112 | } 113 | } 114 | 115 | /// Categorizes the cause of a `sexpr::Error`. 116 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] 117 | pub enum Category { 118 | /// The error was caused by a failure to read or write bytes on an IO 119 | /// stream. 120 | Io, 121 | 122 | /// The error was caused by input that was not a syntactically valid S-expression. 123 | Syntax, 124 | 125 | /// The error was caused by input data that was semantically incorrect. 126 | /// 127 | /// For example, an S-expression containing a number is semantically incorrect when the 128 | /// type being deserialized into holds a String. 129 | Data, 130 | 131 | /// The error was caused by prematurely reaching the end of the input data. 132 | /// 133 | /// Callers that process streaming input may be interested in retrying the 134 | /// deserialization once more data is available. 135 | Eof, 136 | } 137 | 138 | impl From for io::Error { 139 | /// Convert a `sexpr::Error` into an `io::Error`. 140 | /// 141 | /// Sexprs syntax and data errors are turned into `InvalidData` IO errors. 142 | /// EOF errors are turned into `UnexpectedEof` IO errors. 143 | /// 144 | /// ```rust,ignore 145 | /// use std::io; 146 | /// 147 | /// enum MyError { 148 | /// Io(io::Error), 149 | /// Sexp(sexpr::Error), 150 | /// } 151 | /// 152 | /// impl From for MyError { 153 | /// fn from(err: sexpr::Error) -> MyError { 154 | /// use sexpr::error::Category; 155 | /// match err.classify() { 156 | /// Category::Io => { 157 | /// MyError::Io(err.into()) 158 | /// } 159 | /// Category::Syntax | Category::Data | Category::Eof => { 160 | /// MyError::Sexp(err) 161 | /// } 162 | /// } 163 | /// } 164 | /// } 165 | /// ``` 166 | fn from(j: Error) -> Self { 167 | if let ErrorCode::Io(err) = j.err.code { 168 | err 169 | } else { 170 | match j.classify() { 171 | Category::Io => unreachable!(), 172 | Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j), 173 | Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j), 174 | } 175 | } 176 | } 177 | } 178 | 179 | #[derive(Debug)] 180 | struct ErrorImpl { 181 | code: ErrorCode, 182 | line: usize, 183 | column: usize, 184 | } 185 | 186 | // Not public API. Should be pub(crate). 187 | #[doc(hidden)] 188 | #[derive(Debug)] 189 | pub enum ErrorCode { 190 | /// Catchall for syntax error messages 191 | Message(String), 192 | 193 | /// Some IO error occurred while serializing or deserializing. 194 | Io(io::Error), 195 | 196 | /// EOF while parsing a list. 197 | EofWhileParsingList, 198 | 199 | /// EOF while parsing an object. 200 | EofWhileParsingAlist, 201 | 202 | /// EOF while parsing a string. 203 | EofWhileParsingString, 204 | 205 | /// EOF while parsing a S-expression value. 206 | EofWhileParsingValue, 207 | 208 | /// Expected this character to be a `'.'`. 209 | ExpectedPairDot, 210 | 211 | /// Expected this character to be either a space or `')'``. 212 | ExpectedListEltOrEnd, 213 | 214 | /// Expected this character to be either a `'.'` or a `')'`. 215 | ExpectedPairOrEnd, 216 | 217 | /// Expected this character to be either a `'('` 218 | ExpectedList, 219 | 220 | /// Expected to parse either a `#t`, `#f`, or a `#nil`. 221 | ExpectedSomeIdent, 222 | 223 | /// Expected this character to start an S-expression value. 224 | ExpectedSomeValue, 225 | 226 | /// Expected this character to start an S-expression string, symbol or keyword. 227 | ExpectedSomeString, 228 | 229 | /// Invalid hex escape code. 230 | InvalidEscape, 231 | 232 | /// Invalid number. 233 | InvalidNumber, 234 | 235 | /// Number is bigger than the maximum value of its type. 236 | NumberOutOfRange, 237 | 238 | /// Invalid unicode code point. 239 | InvalidUnicodeCodePoint, 240 | 241 | /// Object key is not a string. 242 | KeyMustBeAString, 243 | 244 | /// Lone leading surrogate in hex escape. 245 | LoneLeadingSurrogateInHexEscape, 246 | 247 | /// S-expression has non-whitespace trailing characters after the value. 248 | TrailingCharacters, 249 | 250 | /// Unexpected end of hex excape. 251 | UnexpectedEndOfHexEscape, 252 | 253 | /// Encountered nesting of S-expression maps and arrays more than 128 layers deep. 254 | RecursionLimitExceeded, 255 | } 256 | 257 | impl Error { 258 | // Not public API. Should be pub(crate). 259 | #[doc(hidden)] 260 | pub fn syntax(code: ErrorCode, line: usize, column: usize) -> Self { 261 | Error { 262 | err: Box::new( 263 | ErrorImpl { 264 | code: code, 265 | line: line, 266 | column: column, 267 | }, 268 | ), 269 | } 270 | } 271 | 272 | // Not public API. Should be pub(crate). 273 | #[doc(hidden)] 274 | pub fn io(error: io::Error) -> Self { 275 | Error { 276 | err: Box::new( 277 | ErrorImpl { 278 | code: ErrorCode::Io(error), 279 | line: 0, 280 | column: 0, 281 | }, 282 | ), 283 | } 284 | } 285 | 286 | // Not public API. Should be pub(crate). 287 | #[doc(hidden)] 288 | pub fn fix_position(self, f: F) -> Self 289 | where 290 | F: FnOnce(ErrorCode) -> Error, 291 | { 292 | if self.err.line == 0 { 293 | f(self.err.code) 294 | } else { 295 | self 296 | } 297 | } 298 | } 299 | 300 | impl Display for ErrorCode { 301 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 302 | match *self { 303 | ErrorCode::Message(ref msg) => f.write_str(msg), 304 | ErrorCode::Io(ref err) => Display::fmt(err, f), 305 | ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"), 306 | ErrorCode::EofWhileParsingAlist => f.write_str("EOF while parsing an alist"), 307 | ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"), 308 | ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"), 309 | ErrorCode::ExpectedPairDot => f.write_str("expected `.`"), 310 | ErrorCode::ExpectedListEltOrEnd => f.write_str("expected ` ` or `)`"), 311 | ErrorCode::ExpectedPairOrEnd => f.write_str("expected `.` or `)`"), 312 | ErrorCode::ExpectedList => f.write_str("expected `(`"), 313 | ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"), 314 | ErrorCode::ExpectedSomeValue => f.write_str("expected value"), 315 | ErrorCode::ExpectedSomeString => f.write_str("expected string"), 316 | ErrorCode::InvalidEscape => f.write_str("invalid escape"), 317 | ErrorCode::InvalidNumber => f.write_str("invalid number"), 318 | ErrorCode::NumberOutOfRange => f.write_str("number out of range"), 319 | ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"), 320 | ErrorCode::KeyMustBeAString => f.write_str("key must be a string"), 321 | ErrorCode::LoneLeadingSurrogateInHexEscape => { 322 | f.write_str("lone leading surrogate in hex escape") 323 | } 324 | ErrorCode::TrailingCharacters => f.write_str("trailing characters"), 325 | ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"), 326 | ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"), 327 | } 328 | } 329 | } 330 | 331 | impl error::Error for Error { 332 | fn description(&self) -> &str { 333 | match self.err.code { 334 | ErrorCode::Io(ref err) => error::Error::description(err), 335 | _ => { 336 | // If you want a better message, use Display::fmt or to_string(). 337 | "S-expression error" 338 | } 339 | } 340 | } 341 | 342 | fn cause(&self) -> Option<&error::Error> { 343 | match self.err.code { 344 | ErrorCode::Io(ref err) => Some(err), 345 | _ => None, 346 | } 347 | } 348 | } 349 | 350 | impl Display for Error { 351 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 352 | Display::fmt(&*self.err, f) 353 | } 354 | } 355 | 356 | impl Display for ErrorImpl { 357 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 358 | if self.line == 0 { 359 | Display::fmt(&self.code, f) 360 | } else { 361 | write!( 362 | f, 363 | "{} at line {} column {}", 364 | self.code, 365 | self.line, 366 | self.column 367 | ) 368 | } 369 | } 370 | } 371 | 372 | // Remove two layers of verbosity from the debug representation. Humans often 373 | // end up seeing this representation because it is what unwrap() shows. 374 | impl Debug for Error { 375 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 376 | Debug::fmt(&*self.err, f) 377 | } 378 | } 379 | 380 | impl de::Error for Error { 381 | fn custom(msg: T) -> Error { 382 | Error { 383 | err: Box::new( 384 | ErrorImpl { 385 | code: ErrorCode::Message(msg.to_string()), 386 | line: 0, 387 | column: 0, 388 | }, 389 | ), 390 | } 391 | } 392 | } 393 | 394 | impl ser::Error for Error { 395 | fn custom(msg: T) -> Error { 396 | Error { 397 | err: Box::new( 398 | ErrorImpl { 399 | code: ErrorCode::Message(msg.to_string()), 400 | line: 0, 401 | column: 0, 402 | }, 403 | ), 404 | } 405 | } 406 | } 407 | -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Serde Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use std::io; 10 | 11 | pub struct LineColIterator { 12 | iter: I, 13 | 14 | /// Index of the current line. Characters in the first line of the input 15 | /// (before the first newline character) are in line 1. 16 | line: usize, 17 | 18 | /// Index of the current column. The first character in the input and any 19 | /// characters immediately following a newline character are in column 1. 20 | /// The column is 0 immediately after a newline character has been read. 21 | col: usize, 22 | 23 | /// Byte offset of the start of the current line. This is the sum of lenghts 24 | /// of all previous lines. Keeping track of things this way allows efficient 25 | /// computation of the current line, column, and byte offset while only 26 | /// updating one of the counters in `next()` in the common case. 27 | start_of_line: usize, 28 | } 29 | 30 | impl LineColIterator 31 | where 32 | I: Iterator>, 33 | { 34 | pub fn new(iter: I) -> LineColIterator { 35 | LineColIterator { 36 | iter: iter, 37 | line: 1, 38 | col: 0, 39 | start_of_line: 0, 40 | } 41 | } 42 | 43 | pub fn line(&self) -> usize { 44 | self.line 45 | } 46 | 47 | pub fn col(&self) -> usize { 48 | self.col 49 | } 50 | 51 | pub fn byte_offset(&self) -> usize { 52 | self.start_of_line + self.col 53 | } 54 | } 55 | 56 | impl Iterator for LineColIterator 57 | where 58 | I: Iterator>, 59 | { 60 | type Item = io::Result; 61 | 62 | fn next(&mut self) -> Option> { 63 | match self.iter.next() { 64 | None => None, 65 | Some(Ok(b'\n')) => { 66 | self.start_of_line += self.col + 1; 67 | self.line += 1; 68 | self.col = 0; 69 | Some(Ok(b'\n')) 70 | } 71 | Some(Ok(c)) => { 72 | self.col += 1; 73 | Some(Ok(c)) 74 | } 75 | Some(Err(e)) => Some(Err(e)), 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr "zv" Pellerin. See the COPYRIGHT 2 | // file at the top-level directory of this distribution 3 | // 4 | // Licensed under the MIT License, , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | //! # Sexpr 8 | //! 9 | //! ## What are S-expressions? 10 | //! 11 | //! S-expressions are a lightweight format for representating and transmitting data 12 | //! consisting of parenthesis pairs. 13 | //! 14 | //! ```scheme 15 | //! (package 16 | //! (name "sexpr") 17 | //! (version "0.7.0") 18 | //! (authors ("Zephyr Pellerin ") :only) 19 | //! (license "MIT/Apache-2.0") 20 | //! (description "Multi-format S-expression serialization/deserialization support") 21 | //! (repository "https://github.com/zv/sexpr") 22 | //! (keywords ("sexp","s-exp","sexpr","smtlib")) 23 | //! (categories ("encoding")) 24 | //! (readme "README.org") 25 | //! (documentation "https://zv.github.io/rust/sexpr")) 26 | //! ``` 27 | //! 28 | //! Sexpr also supports more complex types; including keywords with configurable 29 | //! tokens for `true`, `false` and `nil`. 30 | //! 31 | //! ```scheme 32 | //! (define-class rectangle () 33 | //! (width 34 | //! #:init-value #nil ;; Nil value 35 | //! #:settable #t ;; true 36 | //! #:guard (> width 10) 37 | //! ) 38 | //! (height 39 | //! #:init-value 10 40 | //! #:writable #f ;; false 41 | //! ) 42 | //! ) 43 | //! ``` 44 | //! 45 | //! Here are some common ways in which you might use sexpr. 46 | //! 47 | //! - **As text data**: An unprocessed string of s-expressions that you recieve from 48 | //! some HTTP endpoint, read from a file, or prepare to send to a remote server. 49 | //! - **As untyped data**: Determining if some S-expression is valid before passing 50 | //! it on, or to do basic manipulations like inserting keys or items into a 51 | //! list. 52 | //! - **As a strongly-typed Rust data structure**: When you expect all of your data 53 | //! to conform to a particular structure and you want to get work done without 54 | //! S-expressions loosely-typed struture. 55 | //! 56 | //! Sexpr provides efficient, flexible, safe ways of converting data between 57 | //! each of these representations. 58 | //! 59 | //! # Operating on untyped JSON values 60 | //! 61 | //! Any valid s-exp can be manipulated in the following recursive enum 62 | //! representation. This data structure is [`sexpr::Sexp`][sexp]. 63 | //! 64 | //! ```rust,ignore 65 | //! # use sexpr::{Number, Map}; 66 | //! # 67 | //! # #[allow(dead_code)] 68 | //! enum Sexp { 69 | //! Nil, 70 | //! Symbol(String), 71 | //! String(String), 72 | //! Keyword(String), 73 | //! Number(Number), 74 | //! Boolean(bool), 75 | //! Pair(Box, Box), 76 | //! List(Vec), 77 | //! } 78 | //! ``` 79 | //! 80 | //! A string of S-expressions may be parsed into a `sexpr::Sexp` by the 81 | //! [`sexpr::from_str`][from_str] function. There is also 82 | //! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and 83 | //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or 84 | //! a TCP stream. 85 | //! 86 | //! ```rust,ignore 87 | //! extern crate sexpr; 88 | //! 89 | //! use sexpr::{Sexp, Error}; 90 | //! 91 | //! fn untyped_example() -> Result<(), Error> { 92 | //! // Some s-expressions a &str. 93 | //! let data = r#"( 94 | //! (name . "John Doe") 95 | //! (age . 43) 96 | //! (phones . ( 97 | //! "+44 1234567" 98 | //! "+44 2345678")) 99 | //! )"#; 100 | //! 101 | //! // Parse the string of data into sexpr::Sexp. 102 | //! let v: Sexp = sexpr::from_str(data)?; 103 | //! 104 | //! // Access parts of the data by indexing with square brackets. 105 | //! println!("Please call {} at the number {}", v["name"], v["phones"][0]); 106 | //! 107 | //! Ok(()) 108 | //! } 109 | //! # 110 | //! # fn main() { 111 | //! # untyped_example().unwrap(); 112 | //! # } 113 | //! ``` 114 | //! 115 | //! 116 | //! # Parsing S-expressions as strongly typed data structures 117 | //! 118 | //! Serde provides a powerful way of mapping S-expression data into Rust data 119 | //! structures automatically. 120 | //! 121 | //! ```rust,ignore 122 | //! extern crate serde; 123 | //! extern crate sexpr; 124 | //! 125 | //! #[macro_use] 126 | //! extern crate serde_derive; 127 | //! 128 | //! use sexpr::Error; 129 | //! 130 | //! #[derive(Serialize, Deserialize)] 131 | //! struct Person { 132 | //! name: String, 133 | //! age: u8, 134 | //! phones: Vec, 135 | //! } 136 | //! 137 | //! fn typed_example() -> Result<(), Error> { 138 | //! // Some SEXP input data as a &str. Maybe this comes from the user. 139 | //! let data = r#"( 140 | //! ("name" . "John Doe") 141 | //! ("age" . 43) 142 | //! ("phones" . ( 143 | //! "+44 1234567" 144 | //! "+44 2345678" 145 | //! )) 146 | //! )"#; 147 | //! 148 | //! // Parse the string of data into a Person object. This is exactly the 149 | //! // same function as the one that produced sexpr::Sexp above, but 150 | //! // now we are asking it for a Person as output. 151 | //! let p: Person = sexpr::from_str(data)?; 152 | //! 153 | //! // Do things just like with any other Rust data structure. 154 | //! println!("Please call {} at the number {}", p.name, p.phones[0]); 155 | //! 156 | //! Ok(()) 157 | //! } 158 | //! # 159 | //! # fn main() { 160 | //! # typed_example().unwrap(); 161 | //! # } 162 | //! ``` 163 | //! 164 | //! This is the same `sexpr::from_str` function as before, but this time we 165 | //! assign the return value to a variable of type `Person` so Serde will 166 | //! automatically interpret the input data as a `Person` and produce informative 167 | //! error messages if the layout does not conform to what a `Person` is expected 168 | //! to look like. 169 | //! 170 | //! Any type that implements Serde's `Deserialize` trait can be deserialized 171 | //! this way. This includes built-in Rust standard library types like `Vec` 172 | //! and `HashMap`, as well as any structs or enums annotated with 173 | //! `#[derive(Deserialize)]`. 174 | //! 175 | //! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us 176 | //! use it correctly like they do for any other Rust code. The IDE can 177 | //! autocomplete field names to prevent typos, which was impossible in the 178 | //! `sexpr::Sexp` representation. And the Rust compiler can check that 179 | //! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a 180 | //! `Vec` so indexing into it makes sense and produces a `String`. 181 | //! 182 | //! # Creating S-expressions by serializing data structures 183 | //! 184 | //! A data structure can be converted to a sexp string by 185 | //! [`sexpr::to_string`][to_string]. There is also 186 | //! [`sexpr::to_vec`][to_vec] which serializes to a `Vec` and 187 | //! [`sexpr::to_writer`][to_writer] which serializes to any `io::Write` 188 | //! such as a File or a TCP stream. 189 | //! 190 | //! ```rust,ignore 191 | //! extern crate serde; 192 | //! extern crate sexpr; 193 | //! 194 | //! #[macro_use] 195 | //! extern crate serde_derive; 196 | //! 197 | //! use sexpr::Error; 198 | //! 199 | //! #[derive(Serialize, Deserialize)] 200 | //! struct Address { 201 | //! street: String, 202 | //! city: String, 203 | //! } 204 | //! 205 | //! fn print_an_address() -> Result<(), Error> { 206 | //! // Some data structure. 207 | //! let address = Address { 208 | //! street: "10 Downing Street".to_owned(), 209 | //! city: "London".to_owned(), 210 | //! }; 211 | //! 212 | //! // Serialize it to a SEXP string. 213 | //! let j = sexpr::to_string(&address)?; 214 | //! 215 | //! // Print, write to a file, or send to an HTTP server. 216 | //! println!("{}", j); 217 | //! 218 | //! Ok(()) 219 | //! } 220 | //! # 221 | //! # fn main() { 222 | //! # print_an_address().unwrap(); 223 | //! # } 224 | //! ``` 225 | extern crate num_traits; 226 | // extern crate core; 227 | #[macro_use] 228 | extern crate serde; 229 | extern crate itoa; 230 | extern crate dtoa; 231 | 232 | #[doc(inline)] 233 | pub use self::de::{Deserializer, StreamDeserializer, from_reader, from_slice, from_str}; 234 | #[doc(inline)] 235 | pub use self::error::{Error, Result}; 236 | #[doc(inline)] 237 | pub use ser::{to_string, Serializer}; 238 | #[doc(inline)] 239 | pub use self::sexp::{Sexp, Number, from_value, to_value}; 240 | 241 | #[macro_use] 242 | mod macros; 243 | 244 | pub mod de; 245 | pub mod error; 246 | pub mod ser; 247 | pub mod sexp; 248 | 249 | mod iter; 250 | mod number; 251 | mod atom; 252 | mod read; 253 | -------------------------------------------------------------------------------- /src/macros.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | /// Construct a `sexpr::Sexp` from a S-expression literal. 10 | /// 11 | /// ```rust,ignore 12 | /// # #[macro_use] 13 | /// # extern crate sexpr; 14 | /// # 15 | /// # fn main() { 16 | /// let value: Sexp = sexp!(( 17 | /// ("code" . 200) 18 | /// ("success" . true) 19 | /// ("payload" . 20 | /// ("features" . ("serde" "sexpr"))) 21 | /// )); 22 | /// # } 23 | /// ``` 24 | #[macro_export] 25 | macro_rules! sexp { 26 | ($t:tt) => { 27 | $crate::from_str(stringify!($t)).unwrap(); 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /src/number.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | use error::Error; 3 | use num_traits::NumCast; 4 | use serde::de::{self, Visitor, Unexpected}; 5 | use serde::{Serialize, Serializer, Deserialize, Deserializer}; 6 | use std::fmt::{self, Debug, Display}; 7 | use std::i64; 8 | 9 | /// Represents a Sexp number, whether integer or floating point. 10 | #[derive(Clone, PartialEq)] 11 | pub struct Number { 12 | n: N, 13 | } 14 | 15 | // "N" is a prefix of "NegInt"... this is a false positive. 16 | // https://github.com/Manishearth/rust-clippy/issues/1241 17 | #[cfg_attr(feature = "cargo-clippy", allow(enum_variant_names))] 18 | #[derive(Copy, Clone, Debug, PartialEq)] 19 | enum N { 20 | PosInt(u64), 21 | /// Always less than zero. 22 | NegInt(i64), 23 | /// Always finite. 24 | Float(f64), 25 | } 26 | 27 | impl Number { 28 | #[inline] 29 | pub fn is_i64(&self) -> bool { 30 | match self.n { 31 | N::PosInt(v) => v <= i64::MAX as u64, 32 | N::NegInt(_) => true, 33 | N::Float(_) => false, 34 | } 35 | } 36 | 37 | #[inline] 38 | pub fn is_u64(&self) -> bool { 39 | match self.n { 40 | N::PosInt(_) => true, 41 | N::NegInt(_) | N::Float(_) => false, 42 | } 43 | } 44 | 45 | #[inline] 46 | pub fn is_f64(&self) -> bool { 47 | match self.n { 48 | N::Float(_) => true, 49 | N::PosInt(_) | N::NegInt(_) => false, 50 | } 51 | } 52 | 53 | #[inline] 54 | pub fn as_i64(&self) -> Option { 55 | match self.n { 56 | N::PosInt(n) => NumCast::from(n), 57 | N::NegInt(n) => Some(n), 58 | N::Float(_) => None, 59 | } 60 | } 61 | 62 | #[inline] 63 | pub fn as_u64(&self) -> Option { 64 | match self.n { 65 | N::PosInt(n) => Some(n), 66 | N::NegInt(n) => NumCast::from(n), 67 | N::Float(_) => None, 68 | } 69 | } 70 | 71 | #[inline] 72 | pub fn as_f64(&self) -> Option { 73 | match self.n { 74 | N::PosInt(n) => NumCast::from(n), 75 | N::NegInt(n) => NumCast::from(n), 76 | N::Float(n) => Some(n), 77 | } 78 | } 79 | 80 | #[inline] 81 | pub fn from_f64(f: f64) -> Option { 82 | if f.is_finite() { 83 | Some(Number { n: N::Float(f) }) 84 | } else { 85 | None 86 | } 87 | } 88 | } 89 | 90 | impl fmt::Display for Number { 91 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 92 | match self.n { 93 | N::PosInt(i) => Display::fmt(&i, formatter), 94 | N::NegInt(i) => Display::fmt(&i, formatter), 95 | N::Float(f) => Display::fmt(&f, formatter), 96 | } 97 | } 98 | } 99 | 100 | impl Debug for Number { 101 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 102 | Debug::fmt(&self.n, formatter) 103 | } 104 | } 105 | 106 | impl Serialize for Number { 107 | #[inline] 108 | fn serialize(&self, serializer: S) -> Result 109 | where 110 | S: Serializer, 111 | { 112 | match self.n { 113 | N::PosInt(i) => serializer.serialize_u64(i), 114 | N::NegInt(i) => serializer.serialize_i64(i), 115 | N::Float(f) => serializer.serialize_f64(f), 116 | } 117 | } 118 | } 119 | 120 | impl<'de> Deserialize<'de> for Number { 121 | #[inline] 122 | fn deserialize(deserializer: D) -> Result 123 | where 124 | D: Deserializer<'de>, 125 | { 126 | struct NumberVisitor; 127 | 128 | impl<'de> Visitor<'de> for NumberVisitor { 129 | type Value = Number; 130 | 131 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 132 | formatter.write_str("a number") 133 | } 134 | 135 | #[inline] 136 | fn visit_i64(self, value: i64) -> Result { 137 | Ok(value.into()) 138 | } 139 | 140 | #[inline] 141 | fn visit_u64(self, value: u64) -> Result { 142 | Ok(value.into()) 143 | } 144 | 145 | #[inline] 146 | fn visit_f64(self, value: f64) -> Result 147 | where 148 | E: de::Error, 149 | { 150 | Number::from_f64(value).ok_or_else(|| de::Error::custom("not a Sexp number")) 151 | } 152 | } 153 | 154 | deserializer.deserialize_any(NumberVisitor) 155 | } 156 | } 157 | 158 | impl<'de> Deserializer<'de> for Number { 159 | type Error = Error; 160 | 161 | #[inline] 162 | fn deserialize_any(self, visitor: V) -> Result 163 | where 164 | V: Visitor<'de>, 165 | { 166 | match self.n { 167 | N::PosInt(i) => visitor.visit_u64(i), 168 | N::NegInt(i) => visitor.visit_i64(i), 169 | N::Float(f) => visitor.visit_f64(f), 170 | } 171 | } 172 | 173 | forward_to_deserialize_any! { 174 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 175 | byte_buf option unit unit_struct newtype_struct seq tuple 176 | tuple_struct map struct enum identifier ignored_any 177 | } 178 | } 179 | 180 | impl<'de, 'a> Deserializer<'de> for &'a Number { 181 | type Error = Error; 182 | 183 | #[inline] 184 | fn deserialize_any(self, visitor: V) -> Result 185 | where 186 | V: Visitor<'de>, 187 | { 188 | match self.n { 189 | N::PosInt(i) => visitor.visit_u64(i), 190 | N::NegInt(i) => visitor.visit_i64(i), 191 | N::Float(f) => visitor.visit_f64(f), 192 | } 193 | } 194 | 195 | forward_to_deserialize_any! { 196 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 197 | byte_buf option unit unit_struct newtype_struct seq tuple 198 | tuple_struct map struct enum identifier ignored_any 199 | } 200 | } 201 | 202 | macro_rules! from_signed { 203 | ($($signed_ty:ident)*) => { 204 | $( 205 | impl From<$signed_ty> for Number { 206 | #[inline] 207 | fn from(i: $signed_ty) -> Self { 208 | if i < 0 { 209 | Number { n: N::NegInt(i as i64) } 210 | } else { 211 | Number { n: N::PosInt(i as u64) } 212 | } 213 | } 214 | } 215 | )* 216 | }; 217 | } 218 | 219 | macro_rules! from_unsigned { 220 | ($($unsigned_ty:ident)*) => { 221 | $( 222 | impl From<$unsigned_ty> for Number { 223 | #[inline] 224 | fn from(u: $unsigned_ty) -> Self { 225 | Number { n: N::PosInt(u as u64) } 226 | } 227 | } 228 | )* 229 | }; 230 | } 231 | 232 | from_signed!(i8 i16 i32 i64 isize); 233 | from_unsigned!(u8 u16 u32 u64 usize); 234 | 235 | impl Number { 236 | // Not public API. Should be pub(crate). 237 | #[doc(hidden)] 238 | pub fn unexpected(&self) -> Unexpected { 239 | match self.n { 240 | N::PosInt(u) => Unexpected::Unsigned(u), 241 | N::NegInt(i) => Unexpected::Signed(i), 242 | N::Float(f) => Unexpected::Float(f), 243 | } 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /src/read.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Serde Developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use std::{char, cmp, io, str}; 10 | use std::ops::Deref; 11 | 12 | use iter::LineColIterator; 13 | 14 | use super::error::{Error, ErrorCode, Result}; 15 | 16 | /// Trait used by the deserializer for iterating over input. This is manually 17 | /// "specialized" for iterating over &[u8]. Once feature(specialization) is 18 | /// stable we can use actual specialization. 19 | /// 20 | /// This trait is sealed and cannot be implemented for types outside of 21 | /// `serde_json`. 22 | pub trait Read<'de>: private::Sealed { 23 | #[doc(hidden)] 24 | fn next(&mut self) -> io::Result>; 25 | #[doc(hidden)] 26 | fn peek(&mut self) -> io::Result>; 27 | 28 | /// Only valid after a call to peek(). Discards the peeked byte. 29 | #[doc(hidden)] 30 | fn discard(&mut self); 31 | 32 | /// Position of the most recent call to next(). 33 | /// 34 | /// The most recent call was probably next() and not peek(), but this method 35 | /// should try to return a sensible result if the most recent call was 36 | /// actually peek() because we don't always know. 37 | /// 38 | /// Only called in case of an error, so performance is not important. 39 | #[doc(hidden)] 40 | fn position(&self) -> Position; 41 | 42 | /// Position of the most recent call to peek(). 43 | /// 44 | /// The most recent call was probably peek() and not next(), but this method 45 | /// should try to return a sensible result if the most recent call was 46 | /// actually next() because we don't always know. 47 | /// 48 | /// Only called in case of an error, so performance is not important. 49 | #[doc(hidden)] 50 | fn peek_position(&self) -> Position; 51 | 52 | /// Offset from the beginning of the input to the next byte that would be 53 | /// returned by next() or peek(). 54 | #[doc(hidden)] 55 | fn byte_offset(&self) -> usize; 56 | 57 | /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped 58 | /// string until the next quotation mark using the given scratch space if 59 | /// necessary. The scratch space is initially empty. 60 | #[doc(hidden)] 61 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; 62 | 63 | /// Parses an unescaped string until the next whitespace or list close.. 64 | fn parse_symbol<'s>(&'s mut self, scratch: &'s mut Vec) -> Result>; 65 | 66 | /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped 67 | /// string until the next quotation mark using the given scratch space if 68 | /// necessary. The scratch space is initially empty. 69 | /// 70 | /// This function returns the raw bytes in the string with escape sequences 71 | /// expanded but without performing unicode validation. 72 | #[doc(hidden)] 73 | fn parse_str_raw<'s>( 74 | &'s mut self, 75 | scratch: &'s mut Vec, 76 | ) -> Result>; 77 | } 78 | 79 | pub struct Position { 80 | pub line: usize, 81 | pub column: usize, 82 | } 83 | 84 | pub enum Reference<'b, 'c, T: ?Sized + 'static> { 85 | Borrowed(&'b T), 86 | Copied(&'c T), 87 | } 88 | 89 | impl<'b, 'c, T: ?Sized + 'static> Deref for Reference<'b, 'c, T> { 90 | type Target = T; 91 | 92 | fn deref(&self) -> &Self::Target { 93 | match *self { 94 | Reference::Borrowed(b) => b, 95 | Reference::Copied(c) => c, 96 | } 97 | } 98 | } 99 | 100 | /// JSON input source that reads from a std::io input stream. 101 | pub struct IoRead 102 | where 103 | R: io::Read, 104 | { 105 | iter: LineColIterator>, 106 | /// Temporary storage of peeked byte. 107 | ch: Option, 108 | } 109 | 110 | /// JSON input source that reads from a slice of bytes. 111 | // 112 | // This is more efficient than other iterators because peek() can be read-only 113 | // and we can compute line/col position only if an error happens. 114 | pub struct SliceRead<'a> { 115 | slice: &'a [u8], 116 | /// Index of the *next* byte that will be returned by next() or peek(). 117 | index: usize, 118 | } 119 | 120 | /// JSON input source that reads from a UTF-8 string. 121 | // 122 | // Able to elide UTF-8 checks by assuming that the input is valid UTF-8. 123 | pub struct StrRead<'a> { 124 | delegate: SliceRead<'a>, 125 | } 126 | 127 | // Prevent users from implementing the Read trait. 128 | mod private { 129 | pub trait Sealed {} 130 | } 131 | 132 | ////////////////////////////////////////////////////////////////////////////// 133 | 134 | impl IoRead 135 | where 136 | R: io::Read, 137 | { 138 | /// Create a JSON input source to read from a std::io input stream. 139 | pub fn new(reader: R) -> Self { 140 | IoRead { 141 | iter: LineColIterator::new(reader.bytes()), 142 | ch: None, 143 | } 144 | } 145 | } 146 | 147 | impl private::Sealed for IoRead where R: io::Read { } 148 | 149 | impl IoRead 150 | where 151 | R: io::Read, 152 | { 153 | fn parse_str_bytes<'s, T, F>( 154 | &'s mut self, 155 | scratch: &'s mut Vec, 156 | validate: bool, 157 | result: F, 158 | ) -> Result 159 | where 160 | T: 's, 161 | F: FnOnce(&'s Self, &'s [u8]) -> Result, 162 | { 163 | loop { 164 | let ch = try!(next_or_eof(self)); 165 | if !ESCAPE[ch as usize] { 166 | scratch.push(ch); 167 | continue; 168 | } 169 | match ch { 170 | b'"' => { 171 | return result(self, scratch); 172 | } 173 | b'\\' => { 174 | try!(parse_escape(self, scratch)); 175 | } 176 | _ => { 177 | if validate { 178 | return error(self, ErrorCode::InvalidUnicodeCodePoint); 179 | } 180 | scratch.push(ch); 181 | } 182 | } 183 | } 184 | } 185 | 186 | fn parse_symbol_bytes<'s, T, F>( 187 | &'s mut self, 188 | scratch: &'s mut Vec, 189 | result: F, 190 | ) -> Result 191 | where 192 | T: 's, 193 | F: FnOnce(&'s Self, &'s [u8]) -> Result, 194 | { 195 | loop { 196 | match try!(self.next().map_err(Error::io)) { 197 | Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b')') | None => return result(self, scratch), 198 | Some(ch) => scratch.push(ch), 199 | } 200 | } 201 | } 202 | } 203 | 204 | 205 | 206 | impl<'de, R> Read<'de> for IoRead 207 | where 208 | R: io::Read, 209 | { 210 | #[inline] 211 | fn next(&mut self) -> io::Result> { 212 | match self.ch.take() { 213 | Some(ch) => Ok(Some(ch)), 214 | None => { 215 | match self.iter.next() { 216 | Some(Err(err)) => Err(err), 217 | Some(Ok(ch)) => Ok(Some(ch)), 218 | None => Ok(None), 219 | } 220 | } 221 | } 222 | } 223 | 224 | #[inline] 225 | fn peek(&mut self) -> io::Result> { 226 | match self.ch { 227 | Some(ch) => Ok(Some(ch)), 228 | None => { 229 | match self.iter.next() { 230 | Some(Err(err)) => Err(err), 231 | Some(Ok(ch)) => { 232 | self.ch = Some(ch); 233 | Ok(self.ch) 234 | } 235 | None => Ok(None), 236 | } 237 | } 238 | } 239 | } 240 | 241 | #[inline] 242 | fn discard(&mut self) { 243 | self.ch = None; 244 | } 245 | 246 | fn position(&self) -> Position { 247 | Position { 248 | line: self.iter.line(), 249 | column: self.iter.col(), 250 | } 251 | } 252 | 253 | fn peek_position(&self) -> Position { 254 | // The LineColIterator updates its position during peek() so it has the 255 | // right one here. 256 | self.position() 257 | } 258 | 259 | fn byte_offset(&self) -> usize { 260 | match self.ch { 261 | Some(_) => self.iter.byte_offset() - 1, 262 | None => self.iter.byte_offset(), 263 | } 264 | } 265 | 266 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 267 | self.parse_str_bytes(scratch, true, as_str) 268 | .map(Reference::Copied) 269 | } 270 | 271 | fn parse_str_raw<'s>( 272 | &'s mut self, 273 | scratch: &'s mut Vec, 274 | ) -> Result> { 275 | self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) 276 | .map(Reference::Copied) 277 | } 278 | 279 | fn parse_symbol<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 280 | self.parse_symbol_bytes(scratch, as_str) 281 | .map(Reference::Copied) 282 | } 283 | } 284 | 285 | ////////////////////////////////////////////////////////////////////////////// 286 | 287 | impl<'a> SliceRead<'a> { 288 | /// Create a JSON input source to read from a slice of bytes. 289 | pub fn new(slice: &'a [u8]) -> Self { 290 | SliceRead { 291 | slice: slice, 292 | index: 0, 293 | } 294 | } 295 | 296 | fn position_of_index(&self, i: usize) -> Position { 297 | let mut pos = Position { line: 1, column: 0 }; 298 | for ch in &self.slice[..i] { 299 | match *ch { 300 | b'\n' => { 301 | pos.line += 1; 302 | pos.column = 0; 303 | } 304 | _ => { 305 | pos.column += 1; 306 | } 307 | } 308 | } 309 | pos 310 | } 311 | 312 | fn parse_symbol_bytes<'s, T: ?Sized, F>( 313 | &'s mut self, 314 | scratch: &'s mut Vec, 315 | result: F, 316 | ) -> Result> 317 | where 318 | T: 's, 319 | F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, 320 | { 321 | // Index of the first byte not yet copied into the scratch space. 322 | let start = self.index; 323 | 324 | loop { 325 | match self.slice[self.index] { 326 | b' ' | b'\n' | b'\t' | b'\r' | b')' => { 327 | if scratch.is_empty() { 328 | // Fast path: return a slice of the raw JSON without any 329 | // copying. 330 | let borrowed = &self.slice[start..self.index]; 331 | return result(self, borrowed).map(Reference::Borrowed); 332 | } else { 333 | scratch.extend_from_slice(&self.slice[start..self.index]); 334 | // "as &[u8]" is required for rustc 1.8.0 335 | let copied = scratch as &[u8]; 336 | return result(self, copied).map(Reference::Copied); 337 | } 338 | } 339 | _ => self.index += 1 340 | } 341 | } 342 | } 343 | 344 | /// The big optimization here over IoRead is that if the string contains no 345 | /// backslash escape sequences, the returned &str is a slice of the raw JSON 346 | /// data so we avoid copying into the scratch space. 347 | fn parse_str_bytes<'s, T: ?Sized, F>( 348 | &'s mut self, 349 | scratch: &'s mut Vec, 350 | validate: bool, 351 | result: F, 352 | ) -> Result> 353 | where 354 | T: 's, 355 | F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>, 356 | { 357 | // Index of the first byte not yet copied into the scratch space. 358 | let mut start = self.index; 359 | 360 | loop { 361 | while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] { 362 | self.index += 1; 363 | } 364 | if self.index == self.slice.len() { 365 | return error(self, ErrorCode::EofWhileParsingString); 366 | } 367 | match self.slice[self.index] { 368 | b'"' => { 369 | if scratch.is_empty() { 370 | // Fast path: return a slice of the raw JSON without any 371 | // copying. 372 | let borrowed = &self.slice[start..self.index]; 373 | self.index += 1; 374 | return result(self, borrowed).map(Reference::Borrowed); 375 | } else { 376 | scratch.extend_from_slice(&self.slice[start..self.index]); 377 | // "as &[u8]" is required for rustc 1.8.0 378 | let copied = scratch as &[u8]; 379 | self.index += 1; 380 | return result(self, copied).map(Reference::Copied); 381 | } 382 | } 383 | b'\\' => { 384 | scratch.extend_from_slice(&self.slice[start..self.index]); 385 | self.index += 1; 386 | try!(parse_escape(self, scratch)); 387 | start = self.index; 388 | } 389 | _ => { 390 | if validate { 391 | return error(self, ErrorCode::InvalidUnicodeCodePoint); 392 | } 393 | self.index += 1; 394 | } 395 | } 396 | } 397 | } 398 | } 399 | 400 | impl<'a> private::Sealed for SliceRead<'a> {} 401 | 402 | impl<'a> Read<'a> for SliceRead<'a> { 403 | #[inline] 404 | fn next(&mut self) -> io::Result> { 405 | // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))` 406 | // is about 10% slower. 407 | Ok( 408 | if self.index < self.slice.len() { 409 | let ch = self.slice[self.index]; 410 | self.index += 1; 411 | Some(ch) 412 | } else { 413 | None 414 | }, 415 | ) 416 | } 417 | 418 | #[inline] 419 | fn peek(&mut self) -> io::Result> { 420 | // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower 421 | // for some reason. 422 | Ok( 423 | if self.index < self.slice.len() { 424 | Some(self.slice[self.index]) 425 | } else { 426 | None 427 | }, 428 | ) 429 | } 430 | 431 | #[inline] 432 | fn discard(&mut self) { 433 | self.index += 1; 434 | } 435 | 436 | fn position(&self) -> Position { 437 | self.position_of_index(self.index) 438 | } 439 | 440 | fn peek_position(&self) -> Position { 441 | // Cap it at slice.len() just in case the most recent call was next() 442 | // and it returned the last byte. 443 | self.position_of_index(cmp::min(self.slice.len(), self.index + 1)) 444 | } 445 | 446 | fn byte_offset(&self) -> usize { 447 | self.index 448 | } 449 | 450 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 451 | self.parse_str_bytes(scratch, true, as_str) 452 | } 453 | 454 | fn parse_symbol<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 455 | self.parse_symbol_bytes(scratch, as_str) 456 | } 457 | 458 | fn parse_str_raw<'s>( 459 | &'s mut self, 460 | scratch: &'s mut Vec, 461 | ) -> Result> { 462 | self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes)) 463 | } 464 | } 465 | 466 | ////////////////////////////////////////////////////////////////////////////// 467 | 468 | impl<'a> StrRead<'a> { 469 | /// Create a JSON input source to read from a UTF-8 string. 470 | pub fn new(s: &'a str) -> Self { 471 | StrRead { delegate: SliceRead::new(s.as_bytes()) } 472 | } 473 | } 474 | 475 | impl<'a> private::Sealed for StrRead<'a> {} 476 | 477 | impl<'a> Read<'a> for StrRead<'a> { 478 | #[inline] 479 | fn next(&mut self) -> io::Result> { 480 | self.delegate.next() 481 | } 482 | 483 | #[inline] 484 | fn peek(&mut self) -> io::Result> { 485 | self.delegate.peek() 486 | } 487 | 488 | #[inline] 489 | fn discard(&mut self) { 490 | self.delegate.discard(); 491 | } 492 | 493 | fn position(&self) -> Position { 494 | self.delegate.position() 495 | } 496 | 497 | fn peek_position(&self) -> Position { 498 | self.delegate.peek_position() 499 | } 500 | 501 | fn byte_offset(&self) -> usize { 502 | self.delegate.byte_offset() 503 | } 504 | 505 | fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 506 | self.delegate 507 | .parse_str_bytes( 508 | scratch, true, |_, bytes| { 509 | // The input is assumed to be valid UTF-8 and the \u-escapes are 510 | // checked along the way, so don't need to check here. 511 | Ok(unsafe { str::from_utf8_unchecked(bytes) }) 512 | } 513 | ) 514 | } 515 | 516 | fn parse_symbol<'s>(&'s mut self, scratch: &'s mut Vec) -> Result> { 517 | self.delegate 518 | .parse_symbol_bytes( 519 | scratch, |_, bytes| { 520 | // The input is assumed to be valid UTF-8 and the \u-escapes are 521 | // checked along the way, so don't need to check here. 522 | Ok(unsafe { str::from_utf8_unchecked(bytes) }) 523 | } 524 | ) 525 | } 526 | 527 | fn parse_str_raw<'s>( 528 | &'s mut self, 529 | scratch: &'s mut Vec, 530 | ) -> Result> { 531 | self.delegate.parse_str_raw(scratch) 532 | } 533 | } 534 | 535 | ////////////////////////////////////////////////////////////////////////////// 536 | 537 | const CT: bool = true; // control character \x00...\x1F 538 | const QU: bool = true; // quote \x22 539 | const BS: bool = true; // backslash \x5C 540 | const O: bool = false; // allow unescaped 541 | 542 | // Lookup table of bytes that must be escaped. A value of true at index i means 543 | // that byte i requires an escape sequence in the input. 544 | #[cfg_attr(rustfmt, rustfmt_skip)] 545 | static ESCAPE: [bool; 256] = [ 546 | // 1 2 3 4 5 6 7 8 9 A B C D E F 547 | CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0 548 | CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1 549 | O, O, QU, O, O, O, O, O, O, O, O, O, O, O, O, O, // 2 550 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 3 551 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 4 552 | O, O, O, O, O, O, O, O, O, O, O, O, BS, O, O, O, // 5 553 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 6 554 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 7 555 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 8 556 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // 9 557 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // A 558 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // B 559 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // C 560 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // D 561 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // E 562 | O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, // F 563 | ]; 564 | 565 | fn next_or_eof<'de, R: Read<'de>>(read: &mut R) -> Result { 566 | match try!(read.next().map_err(Error::io)) { 567 | Some(b) => Ok(b), 568 | None => error(read, ErrorCode::EofWhileParsingString), 569 | } 570 | } 571 | 572 | fn error<'de, R: Read<'de>, T>(read: &R, reason: ErrorCode) -> Result { 573 | let pos = read.position(); 574 | Err(Error::syntax(reason, pos.line, pos.column)) 575 | } 576 | 577 | fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> { 578 | str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint)) 579 | } 580 | 581 | /// Parses a JSON escape sequence and appends it into the scratch space. Assumes 582 | /// the previous byte read was a backslash. 583 | fn parse_escape<'de, R: Read<'de>>(read: &mut R, scratch: &mut Vec) -> Result<()> { 584 | let ch = try!(next_or_eof(read)); 585 | 586 | match ch { 587 | b'"' => scratch.push(b'"'), 588 | b'\\' => scratch.push(b'\\'), 589 | b'/' => scratch.push(b'/'), 590 | b'b' => scratch.push(b'\x08'), 591 | b'f' => scratch.push(b'\x0c'), 592 | b'n' => scratch.push(b'\n'), 593 | b'r' => scratch.push(b'\r'), 594 | b't' => scratch.push(b'\t'), 595 | b'u' => { 596 | let c = match try!(decode_hex_escape(read)) { 597 | 0xDC00...0xDFFF => { 598 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 599 | } 600 | 601 | // Non-BMP characters are encoded as a sequence of 602 | // two hex escapes, representing UTF-16 surrogates. 603 | n1 @ 0xD800...0xDBFF => { 604 | if try!(next_or_eof(read)) != b'\\' { 605 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 606 | } 607 | if try!(next_or_eof(read)) != b'u' { 608 | return error(read, ErrorCode::UnexpectedEndOfHexEscape); 609 | } 610 | 611 | let n2 = try!(decode_hex_escape(read)); 612 | 613 | if n2 < 0xDC00 || n2 > 0xDFFF { 614 | return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape); 615 | } 616 | 617 | let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000; 618 | 619 | match char::from_u32(n as u32) { 620 | Some(c) => c, 621 | None => { 622 | return error(read, ErrorCode::InvalidUnicodeCodePoint); 623 | } 624 | } 625 | } 626 | 627 | n => { 628 | match char::from_u32(n as u32) { 629 | Some(c) => c, 630 | None => { 631 | return error(read, ErrorCode::InvalidUnicodeCodePoint); 632 | } 633 | } 634 | } 635 | }; 636 | 637 | // FIXME: this allocation is required in order to be compatible with stable 638 | // rust, which doesn't support encoding a `char` into a stack buffer. 639 | let mut buf = String::new(); 640 | buf.push(c); 641 | scratch.extend(buf.bytes()); 642 | } 643 | _ => { 644 | return error(read, ErrorCode::InvalidEscape); 645 | } 646 | } 647 | 648 | Ok(()) 649 | } 650 | 651 | fn decode_hex_escape<'de, R: Read<'de>>(read: &mut R) -> Result { 652 | let mut n = 0; 653 | for _ in 0..4 { 654 | n = match try!(next_or_eof(read)) { 655 | c @ b'0'...b'9' => n * 16_u16 + ((c as u16) - (b'0' as u16)), 656 | b'a' | b'A' => n * 16_u16 + 10_u16, 657 | b'b' | b'B' => n * 16_u16 + 11_u16, 658 | b'c' | b'C' => n * 16_u16 + 12_u16, 659 | b'd' | b'D' => n * 16_u16 + 13_u16, 660 | b'e' | b'E' => n * 16_u16 + 14_u16, 661 | b'f' | b'F' => n * 16_u16 + 15_u16, 662 | _ => { 663 | return error(read, ErrorCode::InvalidEscape); 664 | } 665 | }; 666 | } 667 | Ok(n) 668 | } 669 | -------------------------------------------------------------------------------- /src/ser.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | //! Serialize a Rust data structure into S-expression data. 10 | 11 | use std::fmt; 12 | use std::io; 13 | use std::num::FpCategory; 14 | use std::str; 15 | 16 | use serde::ser::{self, Impossible}; 17 | use super::error::{Error, ErrorCode, Result}; 18 | 19 | use itoa; 20 | use dtoa; 21 | 22 | /// A structure for serializing Rust values into S-expression. 23 | pub struct Serializer { 24 | writer: W, 25 | formatter: F, 26 | } 27 | 28 | impl Serializer 29 | where 30 | W: io::Write, 31 | { 32 | /// Creates a new S-expression serializer. 33 | #[inline] 34 | pub fn new(writer: W) -> Self { 35 | Serializer::with_formatter(writer, CompactFormatter) 36 | } 37 | } 38 | 39 | impl<'a, W> Serializer> 40 | where 41 | W: io::Write, 42 | { 43 | /// Creates a new S-expression pretty print serializer. 44 | #[inline] 45 | pub fn pretty(writer: W) -> Self { 46 | Serializer::with_formatter(writer, PrettyFormatter::new()) 47 | } 48 | } 49 | 50 | impl Serializer 51 | where 52 | W: io::Write, 53 | F: Formatter, 54 | { 55 | /// Creates a new S-expression visitor whose output will be written to the writer 56 | /// specified. 57 | #[inline] 58 | pub fn with_formatter(writer: W, formatter: F) -> Self { 59 | Serializer { 60 | writer: writer, 61 | formatter: formatter, 62 | } 63 | } 64 | 65 | /// Unwrap the `Writer` from the `Serializer`. 66 | #[inline] 67 | pub fn into_inner(self) -> W { 68 | self.writer 69 | } 70 | } 71 | 72 | impl<'a, W, F> ser::Serializer for &'a mut Serializer 73 | where 74 | W: io::Write, 75 | F: Formatter, 76 | { 77 | type Ok = (); 78 | type Error = Error; 79 | 80 | type SerializeSeq = Compound<'a, W, F>; 81 | type SerializeTuple = Compound<'a, W, F>; 82 | type SerializeTupleStruct = Compound<'a, W, F>; 83 | type SerializeTupleVariant = Compound<'a, W, F>; 84 | type SerializeMap = Compound<'a, W, F>; 85 | type SerializeStruct = Compound<'a, W, F>; 86 | type SerializeStructVariant = Compound<'a, W, F>; 87 | 88 | #[inline] 89 | fn serialize_bool(self, value: bool) -> Result<()> { 90 | try!( 91 | self.formatter 92 | .write_bool(&mut self.writer, value) 93 | .map_err(Error::io) 94 | ); 95 | Ok(()) 96 | } 97 | 98 | #[inline] 99 | fn serialize_i8(self, value: i8) -> Result<()> { 100 | try!( 101 | self.formatter 102 | .write_i8(&mut self.writer, value) 103 | .map_err(Error::io) 104 | ); 105 | Ok(()) 106 | } 107 | 108 | #[inline] 109 | fn serialize_i16(self, value: i16) -> Result<()> { 110 | try!( 111 | self.formatter 112 | .write_i16(&mut self.writer, value) 113 | .map_err(Error::io) 114 | ); 115 | Ok(()) 116 | } 117 | 118 | #[inline] 119 | fn serialize_i32(self, value: i32) -> Result<()> { 120 | try!( 121 | self.formatter 122 | .write_i32(&mut self.writer, value) 123 | .map_err(Error::io) 124 | ); 125 | Ok(()) 126 | } 127 | 128 | #[inline] 129 | fn serialize_i64(self, value: i64) -> Result<()> { 130 | try!( 131 | self.formatter 132 | .write_i64(&mut self.writer, value) 133 | .map_err(Error::io) 134 | ); 135 | Ok(()) 136 | } 137 | 138 | #[inline] 139 | fn serialize_u8(self, value: u8) -> Result<()> { 140 | try!( 141 | self.formatter 142 | .write_u8(&mut self.writer, value) 143 | .map_err(Error::io) 144 | ); 145 | Ok(()) 146 | } 147 | 148 | #[inline] 149 | fn serialize_u16(self, value: u16) -> Result<()> { 150 | try!( 151 | self.formatter 152 | .write_u16(&mut self.writer, value) 153 | .map_err(Error::io) 154 | ); 155 | Ok(()) 156 | } 157 | 158 | #[inline] 159 | fn serialize_u32(self, value: u32) -> Result<()> { 160 | try!( 161 | self.formatter 162 | .write_u32(&mut self.writer, value) 163 | .map_err(Error::io) 164 | ); 165 | Ok(()) 166 | } 167 | 168 | #[inline] 169 | fn serialize_u64(self, value: u64) -> Result<()> { 170 | try!( 171 | self.formatter 172 | .write_u64(&mut self.writer, value) 173 | .map_err(Error::io) 174 | ); 175 | Ok(()) 176 | } 177 | 178 | #[inline] 179 | fn serialize_f32(self, value: f32) -> Result<()> { 180 | match value.classify() { 181 | FpCategory::Nan | FpCategory::Infinite => { 182 | try!( 183 | self.formatter 184 | .write_null(&mut self.writer) 185 | .map_err(Error::io) 186 | ); 187 | } 188 | _ => { 189 | try!( 190 | self.formatter 191 | .write_f32(&mut self.writer, value) 192 | .map_err(Error::io) 193 | ); 194 | } 195 | } 196 | Ok(()) 197 | } 198 | 199 | #[inline] 200 | fn serialize_f64(self, value: f64) -> Result<()> { 201 | match value.classify() { 202 | FpCategory::Nan | FpCategory::Infinite => { 203 | try!( 204 | self.formatter 205 | .write_null(&mut self.writer) 206 | .map_err(Error::io) 207 | ); 208 | } 209 | _ => { 210 | try!( 211 | self.formatter 212 | .write_f64(&mut self.writer, value) 213 | .map_err(Error::io) 214 | ); 215 | } 216 | } 217 | Ok(()) 218 | } 219 | 220 | #[inline] 221 | fn serialize_char(self, value: char) -> Result<()> { 222 | try!(format_escaped_char(&mut self.writer, &mut self.formatter, value).map_err(Error::io)); 223 | Ok(()) 224 | } 225 | 226 | #[inline] 227 | fn serialize_str(self, value: &str) -> Result<()> { 228 | try!(format_escaped_str(&mut self.writer, 229 | &mut self.formatter, value).map_err(Error::io)); 230 | Ok(()) 231 | } 232 | 233 | #[inline] 234 | fn serialize_bytes(self, value: &[u8]) -> Result<()> { 235 | use serde::ser::SerializeSeq; 236 | let mut seq = try!(self.serialize_seq(Some(value.len()))); 237 | for byte in value { 238 | try!(seq.serialize_element(byte)); 239 | } 240 | seq.end() 241 | } 242 | 243 | #[inline] 244 | fn serialize_unit(self) -> Result<()> { 245 | try!( 246 | self.formatter 247 | .write_null(&mut self.writer) 248 | .map_err(Error::io) 249 | ); 250 | Ok(()) 251 | } 252 | 253 | #[inline] 254 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { 255 | self.serialize_unit() 256 | } 257 | 258 | #[inline] 259 | fn serialize_unit_variant( 260 | self, 261 | _name: &'static str, 262 | _variant_index: u32, 263 | variant: &'static str, 264 | ) -> Result<()> { 265 | self.serialize_str(variant) 266 | } 267 | 268 | /// Serialize newtypes without an object wrapper. 269 | #[inline] 270 | fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> 271 | where 272 | T: ser::Serialize, 273 | { 274 | try!( 275 | self.formatter 276 | .write_bare_string(&mut self.writer, value) 277 | .map_err(Error::io) 278 | ); 279 | Ok(()) 280 | } 281 | 282 | #[inline] 283 | fn serialize_newtype_variant( 284 | self, 285 | _name: &'static str, 286 | _variant_index: u32, 287 | variant: &'static str, 288 | value: &T, 289 | ) -> Result<()> 290 | where 291 | T: ser::Serialize, 292 | { 293 | try!( 294 | self.formatter 295 | .begin_object(&mut self.writer) 296 | .map_err(Error::io) 297 | ); 298 | try!( 299 | self.formatter 300 | .begin_object_key(&mut self.writer, true) 301 | .map_err(Error::io) 302 | ); 303 | try!(self.serialize_str(variant)); 304 | try!( 305 | self.formatter 306 | .end_object_key(&mut self.writer) 307 | .map_err(Error::io) 308 | ); 309 | try!( 310 | self.formatter 311 | .begin_object_value(&mut self.writer) 312 | .map_err(Error::io) 313 | ); 314 | try!(value.serialize(&mut *self)); 315 | try!( 316 | self.formatter 317 | .end_object_value(&mut self.writer) 318 | .map_err(Error::io) 319 | ); 320 | try!( 321 | self.formatter 322 | .end_object(&mut self.writer) 323 | .map_err(Error::io) 324 | ); 325 | Ok(()) 326 | } 327 | 328 | #[inline] 329 | fn serialize_none(self) -> Result<()> { 330 | self.serialize_unit() 331 | } 332 | 333 | #[inline] 334 | fn serialize_some(self, value: &T) -> Result<()> 335 | where 336 | T: ser::Serialize, 337 | { 338 | value.serialize(self) 339 | } 340 | 341 | #[inline] 342 | fn serialize_seq(self, len: Option) -> Result { 343 | if len == Some(0) { 344 | try!( 345 | self.formatter 346 | .begin_array(&mut self.writer) 347 | .map_err(Error::io) 348 | ); 349 | try!( 350 | self.formatter 351 | .end_array(&mut self.writer) 352 | .map_err(Error::io) 353 | ); 354 | Ok( 355 | Compound { 356 | ser: self, 357 | state: State::Empty, 358 | }, 359 | ) 360 | } else { 361 | try!( 362 | self.formatter 363 | .begin_array(&mut self.writer) 364 | .map_err(Error::io) 365 | ); 366 | Ok( 367 | Compound { 368 | ser: self, 369 | state: State::First, 370 | }, 371 | ) 372 | } 373 | } 374 | 375 | #[inline] 376 | fn serialize_tuple(self, len: usize) -> Result { 377 | self.serialize_seq(Some(len)) 378 | } 379 | 380 | #[inline] 381 | fn serialize_tuple_struct( 382 | self, 383 | _name: &'static str, 384 | len: usize, 385 | ) -> Result { 386 | self.serialize_seq(Some(len)) 387 | } 388 | 389 | #[inline] 390 | fn serialize_tuple_variant( 391 | self, 392 | _name: &'static str, 393 | _variant_index: u32, 394 | variant: &'static str, 395 | len: usize, 396 | ) -> Result { 397 | try!( 398 | self.formatter 399 | .begin_object(&mut self.writer) 400 | .map_err(Error::io) 401 | ); 402 | try!( 403 | self.formatter 404 | .begin_object_key(&mut self.writer, true) 405 | .map_err(Error::io) 406 | ); 407 | try!(self.serialize_str(variant)); 408 | try!( 409 | self.formatter 410 | .end_object_key(&mut self.writer) 411 | .map_err(Error::io) 412 | ); 413 | try!( 414 | self.formatter 415 | .begin_object_value(&mut self.writer) 416 | .map_err(Error::io) 417 | ); 418 | self.serialize_seq(Some(len)) 419 | } 420 | 421 | #[inline] 422 | fn serialize_map(self, len: Option) -> Result { 423 | if len == Some(0) { 424 | try!( 425 | self.formatter 426 | .begin_object(&mut self.writer) 427 | .map_err(Error::io) 428 | ); 429 | try!( 430 | self.formatter 431 | .end_object(&mut self.writer) 432 | .map_err(Error::io) 433 | ); 434 | Ok( 435 | Compound { 436 | ser: self, 437 | state: State::Empty, 438 | }, 439 | ) 440 | } else { 441 | try!( 442 | self.formatter 443 | .begin_object(&mut self.writer) 444 | .map_err(Error::io) 445 | ); 446 | Ok( 447 | Compound { 448 | ser: self, 449 | state: State::First, 450 | }, 451 | ) 452 | } 453 | } 454 | 455 | #[inline] 456 | fn serialize_struct(self, _name: &'static str, len: usize) -> Result { 457 | self.serialize_map(Some(len)) 458 | } 459 | 460 | #[inline] 461 | fn serialize_struct_variant( 462 | self, 463 | _name: &'static str, 464 | _variant_index: u32, 465 | variant: &'static str, 466 | len: usize, 467 | ) -> Result { 468 | try!( 469 | self.formatter 470 | .begin_object(&mut self.writer) 471 | .map_err(Error::io) 472 | ); 473 | try!( 474 | self.formatter 475 | .begin_object_key(&mut self.writer, true) 476 | .map_err(Error::io) 477 | ); 478 | try!(self.serialize_str(variant)); 479 | try!( 480 | self.formatter 481 | .end_object_key(&mut self.writer) 482 | .map_err(Error::io) 483 | ); 484 | try!( 485 | self.formatter 486 | .begin_object_value(&mut self.writer) 487 | .map_err(Error::io) 488 | ); 489 | self.serialize_map(Some(len)) 490 | } 491 | 492 | fn collect_str(self, value: &T) -> Result 493 | where 494 | T: fmt::Display, 495 | { 496 | use std::fmt::Write; 497 | 498 | struct Adapter<'ser, W: 'ser, F: 'ser> { 499 | writer: &'ser mut W, 500 | formatter: &'ser mut F, 501 | error: Option, 502 | } 503 | 504 | impl<'ser, W, F> Write for Adapter<'ser, W, F> 505 | where 506 | W: io::Write, 507 | F: Formatter, 508 | { 509 | fn write_str(&mut self, s: &str) -> fmt::Result { 510 | assert!(self.error.is_none()); 511 | match format_escaped_str_contents(self.writer, self.formatter, s) { 512 | Ok(()) => Ok(()), 513 | Err(err) => { 514 | self.error = Some(err); 515 | Err(fmt::Error) 516 | } 517 | } 518 | } 519 | } 520 | 521 | try!( 522 | self.formatter 523 | .begin_string(&mut self.writer) 524 | .map_err(Error::io) 525 | ); 526 | { 527 | let mut adapter = Adapter { 528 | writer: &mut self.writer, 529 | formatter: &mut self.formatter, 530 | error: None, 531 | }; 532 | match write!(adapter, "{}", value) { 533 | Ok(()) => assert!(adapter.error.is_none()), 534 | Err(fmt::Error) => { 535 | return Err(Error::io(adapter.error.expect("there should be an error"))); 536 | } 537 | } 538 | } 539 | try!( 540 | self.formatter 541 | .end_string(&mut self.writer) 542 | .map_err(Error::io) 543 | ); 544 | Ok(()) 545 | } 546 | } 547 | 548 | #[doc(hidden)] 549 | #[derive(Eq, PartialEq)] 550 | pub enum State { 551 | Empty, 552 | First, 553 | Rest, 554 | } 555 | 556 | #[doc(hidden)] 557 | pub struct Compound<'a, W: 'a, F: 'a> { 558 | ser: &'a mut Serializer, 559 | state: State, 560 | } 561 | 562 | impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F> 563 | where 564 | W: io::Write, 565 | F: Formatter, 566 | { 567 | type Ok = (); 568 | type Error = Error; 569 | 570 | #[inline] 571 | fn serialize_element(&mut self, value: &T) -> Result<()> 572 | where 573 | T: ser::Serialize, 574 | { 575 | try!( 576 | self.ser 577 | .formatter 578 | .begin_array_value(&mut self.ser.writer, self.state == State::First) 579 | .map_err(Error::io) 580 | ); 581 | self.state = State::Rest; 582 | try!(value.serialize(&mut *self.ser)); 583 | try!( 584 | self.ser 585 | .formatter 586 | .end_array_value(&mut self.ser.writer) 587 | .map_err(Error::io) 588 | ); 589 | Ok(()) 590 | } 591 | 592 | #[inline] 593 | fn end(self) -> Result<()> { 594 | match self.state { 595 | State::Empty => {} 596 | _ => { 597 | try!( 598 | self.ser 599 | .formatter 600 | .end_array(&mut self.ser.writer) 601 | .map_err(Error::io) 602 | ) 603 | } 604 | } 605 | Ok(()) 606 | } 607 | } 608 | 609 | impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F> 610 | where 611 | W: io::Write, 612 | F: Formatter, 613 | { 614 | type Ok = (); 615 | type Error = Error; 616 | 617 | #[inline] 618 | fn serialize_element(&mut self, value: &T) -> Result<()> 619 | where 620 | T: ser::Serialize, 621 | { 622 | ser::SerializeSeq::serialize_element(self, value) 623 | } 624 | 625 | #[inline] 626 | fn end(self) -> Result<()> { 627 | ser::SerializeSeq::end(self) 628 | } 629 | } 630 | 631 | impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F> 632 | where 633 | W: io::Write, 634 | F: Formatter, 635 | { 636 | type Ok = (); 637 | type Error = Error; 638 | 639 | #[inline] 640 | fn serialize_field(&mut self, value: &T) -> Result<()> 641 | where 642 | T: ser::Serialize, 643 | { 644 | ser::SerializeSeq::serialize_element(self, value) 645 | } 646 | 647 | #[inline] 648 | fn end(self) -> Result<()> { 649 | ser::SerializeSeq::end(self) 650 | } 651 | } 652 | 653 | impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F> 654 | where 655 | W: io::Write, 656 | F: Formatter, 657 | { 658 | type Ok = (); 659 | type Error = Error; 660 | 661 | #[inline] 662 | fn serialize_field(&mut self, value: &T) -> Result<()> 663 | where 664 | T: ser::Serialize, 665 | { 666 | ser::SerializeSeq::serialize_element(self, value) 667 | } 668 | 669 | #[inline] 670 | fn end(self) -> Result<()> { 671 | match self.state { 672 | State::Empty => {} 673 | _ => { 674 | try!( 675 | self.ser 676 | .formatter 677 | .end_array(&mut self.ser.writer) 678 | .map_err(Error::io) 679 | ) 680 | } 681 | } 682 | try!( 683 | self.ser 684 | .formatter 685 | .end_object_value(&mut self.ser.writer) 686 | .map_err(Error::io) 687 | ); 688 | try!( 689 | self.ser 690 | .formatter 691 | .end_object(&mut self.ser.writer) 692 | .map_err(Error::io) 693 | ); 694 | Ok(()) 695 | } 696 | } 697 | 698 | impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F> 699 | where 700 | W: io::Write, 701 | F: Formatter, 702 | { 703 | type Ok = (); 704 | type Error = Error; 705 | 706 | #[inline] 707 | fn serialize_key(&mut self, key: &T) -> Result<()> 708 | where 709 | T: ser::Serialize, 710 | { 711 | try!( 712 | self.ser 713 | .formatter 714 | .begin_object_key(&mut self.ser.writer, self.state == State::First) 715 | .map_err(Error::io) 716 | ); 717 | self.state = State::Rest; 718 | 719 | try!(key.serialize(MapKeySerializer { ser: self.ser })); 720 | 721 | try!( 722 | self.ser 723 | .formatter 724 | .end_object_key(&mut self.ser.writer) 725 | .map_err(Error::io) 726 | ); 727 | Ok(()) 728 | } 729 | 730 | #[inline] 731 | fn serialize_value(&mut self, value: &T) -> Result<()> 732 | where 733 | T: ser::Serialize, 734 | { 735 | try!( 736 | self.ser 737 | .formatter 738 | .begin_object_value(&mut self.ser.writer) 739 | .map_err(Error::io) 740 | ); 741 | try!(value.serialize(&mut *self.ser)); 742 | try!( 743 | self.ser 744 | .formatter 745 | .end_object_value(&mut self.ser.writer) 746 | .map_err(Error::io) 747 | ); 748 | Ok(()) 749 | } 750 | 751 | #[inline] 752 | fn end(self) -> Result<()> { 753 | match self.state { 754 | State::Empty => {} 755 | _ => { 756 | try!( 757 | self.ser 758 | .formatter 759 | .end_object(&mut self.ser.writer) 760 | .map_err(Error::io) 761 | ) 762 | } 763 | } 764 | Ok(()) 765 | } 766 | } 767 | 768 | impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F> 769 | where 770 | W: io::Write, 771 | F: Formatter, 772 | { 773 | type Ok = (); 774 | type Error = Error; 775 | 776 | #[inline] 777 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> 778 | where 779 | T: ser::Serialize, 780 | { 781 | try!(ser::SerializeMap::serialize_key(self, key)); 782 | ser::SerializeMap::serialize_value(self, value) 783 | } 784 | 785 | #[inline] 786 | fn end(self) -> Result<()> { 787 | ser::SerializeMap::end(self) 788 | } 789 | } 790 | 791 | impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F> 792 | where 793 | W: io::Write, 794 | F: Formatter, 795 | { 796 | type Ok = (); 797 | type Error = Error; 798 | 799 | #[inline] 800 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<()> 801 | where 802 | T: ser::Serialize, 803 | { 804 | ser::SerializeStruct::serialize_field(self, key, value) 805 | } 806 | 807 | #[inline] 808 | fn end(self) -> Result<()> { 809 | match self.state { 810 | State::Empty => {} 811 | _ => { 812 | try!( 813 | self.ser 814 | .formatter 815 | .end_object(&mut self.ser.writer) 816 | .map_err(Error::io) 817 | ) 818 | } 819 | } 820 | try!( 821 | self.ser 822 | .formatter 823 | .end_object_value(&mut self.ser.writer) 824 | .map_err(Error::io) 825 | ); 826 | try!( 827 | self.ser 828 | .formatter 829 | .end_object(&mut self.ser.writer) 830 | .map_err(Error::io) 831 | ); 832 | Ok(()) 833 | } 834 | } 835 | 836 | struct MapKeySerializer<'a, W: 'a, F: 'a> { 837 | ser: &'a mut Serializer, 838 | } 839 | 840 | fn key_must_be_a_string() -> Error { 841 | Error::syntax(ErrorCode::KeyMustBeAString, 0, 0) 842 | } 843 | 844 | impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F> 845 | where 846 | W: io::Write, 847 | F: Formatter, 848 | { 849 | type Ok = (); 850 | type Error = Error; 851 | 852 | #[inline] 853 | fn serialize_str(self, value: &str) -> Result<()> { 854 | self.ser.serialize_str(value) 855 | } 856 | 857 | #[inline] 858 | fn serialize_unit_variant( 859 | self, 860 | _name: &'static str, 861 | _variant_index: u32, 862 | variant: &'static str, 863 | ) -> Result<()> { 864 | self.ser.serialize_str(variant) 865 | } 866 | 867 | #[inline] 868 | fn serialize_newtype_struct(self, _name: &'static str, value: &T) -> Result<()> 869 | where 870 | T: ser::Serialize, 871 | { 872 | value.serialize(self) 873 | } 874 | 875 | type SerializeSeq = Impossible<(), Error>; 876 | type SerializeTuple = Impossible<(), Error>; 877 | type SerializeTupleStruct = Impossible<(), Error>; 878 | type SerializeTupleVariant = Impossible<(), Error>; 879 | type SerializeMap = Impossible<(), Error>; 880 | type SerializeStruct = Impossible<(), Error>; 881 | type SerializeStructVariant = Impossible<(), Error>; 882 | 883 | fn serialize_bool(self, _value: bool) -> Result<()> { 884 | Err(key_must_be_a_string()) 885 | } 886 | 887 | fn serialize_i8(self, value: i8) -> Result<()> { 888 | try!( 889 | self.ser 890 | .formatter 891 | .begin_string(&mut self.ser.writer) 892 | .map_err(Error::io) 893 | ); 894 | try!( 895 | self.ser 896 | .formatter 897 | .write_i8(&mut self.ser.writer, value) 898 | .map_err(Error::io) 899 | ); 900 | try!( 901 | self.ser 902 | .formatter 903 | .end_string(&mut self.ser.writer) 904 | .map_err(Error::io) 905 | ); 906 | Ok(()) 907 | } 908 | 909 | fn serialize_i16(self, value: i16) -> Result<()> { 910 | try!( 911 | self.ser 912 | .formatter 913 | .begin_string(&mut self.ser.writer) 914 | .map_err(Error::io) 915 | ); 916 | try!( 917 | self.ser 918 | .formatter 919 | .write_i16(&mut self.ser.writer, value) 920 | .map_err(Error::io) 921 | ); 922 | try!( 923 | self.ser 924 | .formatter 925 | .end_string(&mut self.ser.writer) 926 | .map_err(Error::io) 927 | ); 928 | Ok(()) 929 | } 930 | 931 | fn serialize_i32(self, value: i32) -> Result<()> { 932 | try!( 933 | self.ser 934 | .formatter 935 | .begin_string(&mut self.ser.writer) 936 | .map_err(Error::io) 937 | ); 938 | try!( 939 | self.ser 940 | .formatter 941 | .write_i32(&mut self.ser.writer, value) 942 | .map_err(Error::io) 943 | ); 944 | try!( 945 | self.ser 946 | .formatter 947 | .end_string(&mut self.ser.writer) 948 | .map_err(Error::io) 949 | ); 950 | Ok(()) 951 | } 952 | 953 | fn serialize_i64(self, value: i64) -> Result<()> { 954 | try!( 955 | self.ser 956 | .formatter 957 | .begin_string(&mut self.ser.writer) 958 | .map_err(Error::io) 959 | ); 960 | try!( 961 | self.ser 962 | .formatter 963 | .write_i64(&mut self.ser.writer, value) 964 | .map_err(Error::io) 965 | ); 966 | try!( 967 | self.ser 968 | .formatter 969 | .end_string(&mut self.ser.writer) 970 | .map_err(Error::io) 971 | ); 972 | Ok(()) 973 | } 974 | 975 | fn serialize_u8(self, value: u8) -> Result<()> { 976 | try!( 977 | self.ser 978 | .formatter 979 | .begin_string(&mut self.ser.writer) 980 | .map_err(Error::io) 981 | ); 982 | try!( 983 | self.ser 984 | .formatter 985 | .write_u8(&mut self.ser.writer, value) 986 | .map_err(Error::io) 987 | ); 988 | try!( 989 | self.ser 990 | .formatter 991 | .end_string(&mut self.ser.writer) 992 | .map_err(Error::io) 993 | ); 994 | Ok(()) 995 | } 996 | 997 | fn serialize_u16(self, value: u16) -> Result<()> { 998 | try!( 999 | self.ser 1000 | .formatter 1001 | .begin_string(&mut self.ser.writer) 1002 | .map_err(Error::io) 1003 | ); 1004 | try!( 1005 | self.ser 1006 | .formatter 1007 | .write_u16(&mut self.ser.writer, value) 1008 | .map_err(Error::io) 1009 | ); 1010 | try!( 1011 | self.ser 1012 | .formatter 1013 | .end_string(&mut self.ser.writer) 1014 | .map_err(Error::io) 1015 | ); 1016 | Ok(()) 1017 | } 1018 | 1019 | fn serialize_u32(self, value: u32) -> Result<()> { 1020 | try!( 1021 | self.ser 1022 | .formatter 1023 | .begin_string(&mut self.ser.writer) 1024 | .map_err(Error::io) 1025 | ); 1026 | try!( 1027 | self.ser 1028 | .formatter 1029 | .write_u32(&mut self.ser.writer, value) 1030 | .map_err(Error::io) 1031 | ); 1032 | try!( 1033 | self.ser 1034 | .formatter 1035 | .end_string(&mut self.ser.writer) 1036 | .map_err(Error::io) 1037 | ); 1038 | Ok(()) 1039 | } 1040 | 1041 | fn serialize_u64(self, value: u64) -> Result<()> { 1042 | try!( 1043 | self.ser 1044 | .formatter 1045 | .begin_string(&mut self.ser.writer) 1046 | .map_err(Error::io) 1047 | ); 1048 | try!( 1049 | self.ser 1050 | .formatter 1051 | .write_u64(&mut self.ser.writer, value) 1052 | .map_err(Error::io) 1053 | ); 1054 | try!( 1055 | self.ser 1056 | .formatter 1057 | .end_string(&mut self.ser.writer) 1058 | .map_err(Error::io) 1059 | ); 1060 | Ok(()) 1061 | } 1062 | 1063 | fn serialize_f32(self, _value: f32) -> Result<()> { 1064 | Err(key_must_be_a_string()) 1065 | } 1066 | 1067 | fn serialize_f64(self, _value: f64) -> Result<()> { 1068 | Err(key_must_be_a_string()) 1069 | } 1070 | 1071 | fn serialize_char(self, _value: char) -> Result<()> { 1072 | Err(key_must_be_a_string()) 1073 | } 1074 | 1075 | fn serialize_bytes(self, _value: &[u8]) -> Result<()> { 1076 | Err(key_must_be_a_string()) 1077 | } 1078 | 1079 | fn serialize_unit(self) -> Result<()> { 1080 | Err(key_must_be_a_string()) 1081 | } 1082 | 1083 | fn serialize_unit_struct(self, _name: &'static str) -> Result<()> { 1084 | Err(key_must_be_a_string()) 1085 | } 1086 | 1087 | fn serialize_newtype_variant( 1088 | self, 1089 | _name: &'static str, 1090 | _variant_index: u32, 1091 | _variant: &'static str, 1092 | _value: &T, 1093 | ) -> Result<()> 1094 | where 1095 | T: ser::Serialize, 1096 | { 1097 | Err(key_must_be_a_string()) 1098 | } 1099 | 1100 | fn serialize_none(self) -> Result<()> { 1101 | Err(key_must_be_a_string()) 1102 | } 1103 | 1104 | fn serialize_some(self, _value: &T) -> Result<()> 1105 | where 1106 | T: ser::Serialize, 1107 | { 1108 | Err(key_must_be_a_string()) 1109 | } 1110 | 1111 | fn serialize_seq(self, _len: Option) -> Result { 1112 | Err(key_must_be_a_string()) 1113 | } 1114 | 1115 | fn serialize_tuple(self, _len: usize) -> Result { 1116 | Err(key_must_be_a_string()) 1117 | } 1118 | 1119 | fn serialize_tuple_struct( 1120 | self, 1121 | _name: &'static str, 1122 | _len: usize, 1123 | ) -> Result { 1124 | Err(key_must_be_a_string()) 1125 | } 1126 | 1127 | fn serialize_tuple_variant( 1128 | self, 1129 | _name: &'static str, 1130 | _variant_index: u32, 1131 | _variant: &'static str, 1132 | _len: usize, 1133 | ) -> Result { 1134 | Err(key_must_be_a_string()) 1135 | } 1136 | 1137 | fn serialize_map(self, _len: Option) -> Result { 1138 | Err(key_must_be_a_string()) 1139 | } 1140 | 1141 | fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { 1142 | Err(key_must_be_a_string()) 1143 | } 1144 | 1145 | fn serialize_struct_variant( 1146 | self, 1147 | _name: &'static str, 1148 | _variant_index: u32, 1149 | _variant: &'static str, 1150 | _len: usize, 1151 | ) -> Result { 1152 | Err(key_must_be_a_string()) 1153 | } 1154 | } 1155 | 1156 | /// Represents a character escape code in a type-safe manner. 1157 | pub enum CharEscape { 1158 | /// An escaped quote `"` 1159 | Quote, 1160 | /// An escaped reverse solidus `\` 1161 | ReverseSolidus, 1162 | /// An escaped solidus `/` 1163 | Solidus, 1164 | /// An escaped backspace character (usually escaped as `\b`) 1165 | Backspace, 1166 | /// An escaped form feed character (usually escaped as `\f`) 1167 | FormFeed, 1168 | /// An escaped line feed character (usually escaped as `\n`) 1169 | LineFeed, 1170 | /// An escaped carriage return character (usually escaped as `\r`) 1171 | CarriageReturn, 1172 | /// An escaped tab character (usually escaped as `\t`) 1173 | Tab, 1174 | /// An escaped ASCII plane control character (usually escaped as 1175 | /// `\u00XX` where `XX` are two hex characters) 1176 | AsciiControl(u8), 1177 | } 1178 | 1179 | impl CharEscape { 1180 | #[inline] 1181 | fn from_escape_table(escape: u8, byte: u8) -> CharEscape { 1182 | match escape { 1183 | self::BB => CharEscape::Backspace, 1184 | self::TT => CharEscape::Tab, 1185 | self::NN => CharEscape::LineFeed, 1186 | self::FF => CharEscape::FormFeed, 1187 | self::RR => CharEscape::CarriageReturn, 1188 | self::QU => CharEscape::Quote, 1189 | self::BS => CharEscape::ReverseSolidus, 1190 | self::U => CharEscape::AsciiControl(byte), 1191 | _ => unreachable!(), 1192 | } 1193 | } 1194 | } 1195 | 1196 | /// This trait abstracts away serializing the S-expression control characters, which allows the user to 1197 | /// optionally pretty print the S-expression output. 1198 | pub trait Formatter { 1199 | /// Writes a `null` value to the specified writer. 1200 | #[inline] 1201 | fn write_null(&mut self, writer: &mut W) -> io::Result<()> 1202 | where 1203 | W: io::Write, 1204 | { 1205 | writer.write_all(b"#nil") 1206 | } 1207 | 1208 | /// Writes a `true` or `false` value to the specified writer. 1209 | #[inline] 1210 | fn write_bool(&mut self, writer: &mut W, value: bool) -> io::Result<()> 1211 | where 1212 | W: io::Write, 1213 | { 1214 | // XXX - This needs to be configurable 1215 | let s = if value { 1216 | b"#t" as &[u8] 1217 | } else { 1218 | b"#f" as &[u8] 1219 | }; 1220 | writer.write_all(s) 1221 | } 1222 | 1223 | /// Writes an integer value like `-123` to the specified writer. 1224 | #[inline] 1225 | fn write_i8(&mut self, writer: &mut W, value: i8) -> io::Result<()> 1226 | where 1227 | W: io::Write, 1228 | { 1229 | itoa::write(writer, value).map(|_| ()) 1230 | } 1231 | 1232 | /// Writes an integer value like `-123` to the specified writer. 1233 | #[inline] 1234 | fn write_i16(&mut self, writer: &mut W, value: i16) -> io::Result<()> 1235 | where 1236 | W: io::Write, 1237 | { 1238 | itoa::write(writer, value).map(|_| ()) 1239 | } 1240 | 1241 | /// Writes an integer value like `-123` to the specified writer. 1242 | #[inline] 1243 | fn write_i32(&mut self, writer: &mut W, value: i32) -> io::Result<()> 1244 | where 1245 | W: io::Write, 1246 | { 1247 | itoa::write(writer, value).map(|_| ()) 1248 | } 1249 | 1250 | /// Writes an integer value like `-123` to the specified writer. 1251 | #[inline] 1252 | fn write_i64(&mut self, writer: &mut W, value: i64) -> io::Result<()> 1253 | where 1254 | W: io::Write, 1255 | { 1256 | itoa::write(writer, value).map(|_| ()) 1257 | } 1258 | 1259 | /// Writes an integer value like `123` to the specified writer. 1260 | #[inline] 1261 | fn write_u8(&mut self, writer: &mut W, value: u8) -> io::Result<()> 1262 | where 1263 | W: io::Write, 1264 | { 1265 | itoa::write(writer, value).map(|_| ()) 1266 | } 1267 | 1268 | /// Writes an integer value like `123` to the specified writer. 1269 | #[inline] 1270 | fn write_u16(&mut self, writer: &mut W, value: u16) -> io::Result<()> 1271 | where 1272 | W: io::Write, 1273 | { 1274 | itoa::write(writer, value).map(|_| ()) 1275 | } 1276 | 1277 | /// Writes an integer value like `123` to the specified writer. 1278 | #[inline] 1279 | fn write_u32(&mut self, writer: &mut W, value: u32) -> io::Result<()> 1280 | where 1281 | W: io::Write, 1282 | { 1283 | itoa::write(writer, value).map(|_| ()) 1284 | } 1285 | 1286 | /// Writes an integer value like `123` to the specified writer. 1287 | #[inline] 1288 | fn write_u64(&mut self, writer: &mut W, value: u64) -> io::Result<()> 1289 | where 1290 | W: io::Write, 1291 | { 1292 | itoa::write(writer, value).map(|_| ()) 1293 | } 1294 | 1295 | /// Writes a floating point value like `-31.26e+12` to the specified writer. 1296 | #[inline] 1297 | fn write_f32(&mut self, writer: &mut W, value: f32) -> io::Result<()> 1298 | where 1299 | W: io::Write, 1300 | { 1301 | dtoa::write(writer, value).map(|_| ()) 1302 | } 1303 | 1304 | /// Writes a floating point value like `-31.26e+12` to the specified writer. 1305 | #[inline] 1306 | fn write_f64(&mut self, writer: &mut W, value: f64) -> io::Result<()> 1307 | where 1308 | W: io::Write, 1309 | { 1310 | dtoa::write(writer, value).map(|_| ()) 1311 | } 1312 | 1313 | /// Write a string without any enclosing quotes 1314 | #[inline] 1315 | fn write_bare_string(&mut self, writer: &mut W, value: &T) -> io::Result<()> 1316 | where 1317 | W: io::Write, 1318 | T: ser::Serialize, 1319 | { 1320 | let n = to_string(value).unwrap(); 1321 | writer.write_all(&n[1 .. n.len() - 1].as_bytes()) 1322 | } 1323 | 1324 | /// Called before each series of `write_string_fragment` and 1325 | /// `write_char_escape`. Writes a `"` to the specified writer. 1326 | #[inline] 1327 | fn begin_string(&mut self, writer: &mut W) -> io::Result<()> 1328 | where 1329 | W: io::Write, 1330 | { 1331 | writer.write_all(b"\"") 1332 | } 1333 | 1334 | /// Called after each series of `write_string_fragment` and 1335 | /// `write_char_escape`. Writes a `"` to the specified writer. 1336 | #[inline] 1337 | fn end_string(&mut self, writer: &mut W) -> io::Result<()> 1338 | where 1339 | W: io::Write, 1340 | { 1341 | writer.write_all(b"\"") 1342 | } 1343 | 1344 | /// Writes a string fragment that doesn't need any escaping to the 1345 | /// specified writer. 1346 | #[inline] 1347 | fn write_string_fragment(&mut self, writer: &mut W, fragment: &str) -> io::Result<()> 1348 | where 1349 | W: io::Write, 1350 | { 1351 | writer.write_all(fragment.as_bytes()) 1352 | } 1353 | 1354 | /// Writes a character escape code to the specified writer. 1355 | #[inline] 1356 | fn write_char_escape( 1357 | &mut self, 1358 | writer: &mut W, 1359 | char_escape: CharEscape, 1360 | ) -> io::Result<()> 1361 | where 1362 | W: io::Write, 1363 | { 1364 | use self::CharEscape::*; 1365 | 1366 | let s = match char_escape { 1367 | Quote => b"\\\"", 1368 | ReverseSolidus => b"\\\\", 1369 | Solidus => b"\\/", 1370 | Backspace => b"\\b", 1371 | FormFeed => b"\\f", 1372 | LineFeed => b"\\n", 1373 | CarriageReturn => b"\\r", 1374 | Tab => b"\\t", 1375 | AsciiControl(byte) => { 1376 | static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef"; 1377 | let bytes = &[ 1378 | b'\\', 1379 | b'u', 1380 | b'0', 1381 | b'0', 1382 | HEX_DIGITS[(byte >> 4) as usize], 1383 | HEX_DIGITS[(byte & 0xF) as usize], 1384 | ]; 1385 | return writer.write_all(bytes); 1386 | } 1387 | }; 1388 | 1389 | writer.write_all(s) 1390 | } 1391 | 1392 | /// Called before every array. Writes a `(` to the specified 1393 | /// writer. 1394 | #[inline] 1395 | fn begin_array(&mut self, writer: &mut W) -> io::Result<()> 1396 | where 1397 | W: io::Write, 1398 | { 1399 | writer.write_all(b"(") 1400 | } 1401 | 1402 | /// Called after every array. Writes a `)` to the specified 1403 | /// writer. 1404 | #[inline] 1405 | fn end_array(&mut self, writer: &mut W) -> io::Result<()> 1406 | where 1407 | W: io::Write, 1408 | { 1409 | writer.write_all(b")") 1410 | } 1411 | 1412 | /// Called before every array value. Writes a space if needed to 1413 | /// the specified writer. 1414 | #[inline] 1415 | fn begin_array_value(&mut self, writer: &mut W, first: bool) -> io::Result<()> 1416 | where 1417 | W: io::Write, 1418 | { 1419 | if first { 1420 | Ok(()) 1421 | } else { 1422 | writer.write_all(b" ") 1423 | } 1424 | } 1425 | 1426 | /// Called after every array value. 1427 | #[inline] 1428 | fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> 1429 | where 1430 | W: io::Write, 1431 | { 1432 | Ok(()) 1433 | } 1434 | 1435 | /// Called before every object. Writes a `(` to the specified 1436 | /// writer. 1437 | #[inline] 1438 | fn begin_object(&mut self, writer: &mut W) -> io::Result<()> 1439 | where 1440 | W: io::Write, 1441 | { 1442 | writer.write_all(b"(") 1443 | } 1444 | 1445 | /// Called after every object. Writes a `)` to the specified 1446 | /// writer. 1447 | #[inline] 1448 | fn end_object(&mut self, writer: &mut W) -> io::Result<()> 1449 | where 1450 | W: io::Write, 1451 | { 1452 | writer.write_all(b")") 1453 | } 1454 | 1455 | /// Called before every object key. 1456 | #[inline] 1457 | fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> 1458 | where 1459 | W: io::Write, 1460 | { 1461 | if first { 1462 | Ok(()) 1463 | } else { 1464 | writer.write_all(b" ") 1465 | } 1466 | } 1467 | 1468 | /// Called after every object key. A `.` should be written to the 1469 | /// specified writer by either this method or 1470 | /// `begin_object_value`. 1471 | #[inline] 1472 | fn end_object_key(&mut self, _writer: &mut W) -> io::Result<()> 1473 | where 1474 | W: io::Write, 1475 | { 1476 | Ok(()) 1477 | } 1478 | 1479 | /// Called before every object value. A `.` should be written to 1480 | /// the specified writer by either this method or 1481 | /// `end_object_key`. 1482 | #[inline] 1483 | fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> 1484 | where 1485 | W: io::Write, 1486 | { 1487 | writer.write_all(b".") 1488 | } 1489 | 1490 | /// Called after every object value. 1491 | #[inline] 1492 | fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> 1493 | where 1494 | W: io::Write, 1495 | { 1496 | Ok(()) 1497 | } 1498 | } 1499 | 1500 | /// This structure compacts a S-expression value with no extra whitespace. 1501 | #[derive(Clone, Debug)] 1502 | pub struct CompactFormatter; 1503 | 1504 | impl Formatter for CompactFormatter {} 1505 | 1506 | /// This structure pretty prints a S-expression value to make it human readable. 1507 | #[derive(Clone, Debug)] 1508 | pub struct PrettyFormatter<'a> { 1509 | current_indent: usize, 1510 | has_value: bool, 1511 | indent: &'a [u8], 1512 | } 1513 | 1514 | impl<'a> PrettyFormatter<'a> { 1515 | /// Construct a pretty printer formatter that defaults to using two spaces for indentation. 1516 | pub fn new() -> Self { 1517 | PrettyFormatter::with_indent(b" ") 1518 | } 1519 | 1520 | /// Construct a pretty printer formatter that uses the `indent` string for indentation. 1521 | pub fn with_indent(indent: &'a [u8]) -> Self { 1522 | PrettyFormatter { 1523 | current_indent: 0, 1524 | has_value: false, 1525 | indent: indent, 1526 | } 1527 | } 1528 | } 1529 | 1530 | impl<'a> Default for PrettyFormatter<'a> { 1531 | fn default() -> Self { 1532 | PrettyFormatter::new() 1533 | } 1534 | } 1535 | 1536 | impl<'a> Formatter for PrettyFormatter<'a> { 1537 | #[inline] 1538 | fn begin_array(&mut self, writer: &mut W) -> io::Result<()> 1539 | where 1540 | W: io::Write, 1541 | { 1542 | self.current_indent += 1; 1543 | self.has_value = false; 1544 | writer.write_all(b"(") 1545 | } 1546 | 1547 | #[inline] 1548 | fn end_array(&mut self, writer: &mut W) -> io::Result<()> 1549 | where 1550 | W: io::Write, 1551 | { 1552 | self.current_indent -= 1; 1553 | 1554 | if self.has_value { 1555 | try!(writer.write_all(b"\n")); 1556 | try!(indent(writer, self.current_indent, self.indent)); 1557 | } 1558 | 1559 | writer.write_all(b")") 1560 | } 1561 | 1562 | #[inline] 1563 | fn begin_array_value(&mut self, writer: &mut W, _first: bool) -> io::Result<()> 1564 | where 1565 | W: io::Write, 1566 | { 1567 | try!(writer.write_all(b"\n")); 1568 | try!(indent(writer, self.current_indent, self.indent)); 1569 | Ok(()) 1570 | } 1571 | 1572 | #[inline] 1573 | fn end_array_value(&mut self, _writer: &mut W) -> io::Result<()> 1574 | where 1575 | W: io::Write, 1576 | { 1577 | self.has_value = true; 1578 | Ok(()) 1579 | } 1580 | 1581 | #[inline] 1582 | fn begin_object(&mut self, writer: &mut W) -> io::Result<()> 1583 | where 1584 | W: io::Write, 1585 | { 1586 | self.current_indent += 1; 1587 | self.has_value = false; 1588 | writer.write_all(b"{") 1589 | } 1590 | 1591 | #[inline] 1592 | fn end_object(&mut self, writer: &mut W) -> io::Result<()> 1593 | where 1594 | W: io::Write, 1595 | { 1596 | self.current_indent -= 1; 1597 | 1598 | if self.has_value { 1599 | try!(writer.write_all(b"\n")); 1600 | try!(indent(writer, self.current_indent, self.indent)); 1601 | } 1602 | 1603 | writer.write_all(b"}") 1604 | } 1605 | 1606 | #[inline] 1607 | fn begin_object_key(&mut self, writer: &mut W, first: bool) -> io::Result<()> 1608 | where 1609 | W: io::Write, 1610 | { 1611 | if first { 1612 | try!(writer.write_all(b"\n")); 1613 | } else { 1614 | try!(writer.write_all(b",\n")); 1615 | } 1616 | indent(writer, self.current_indent, self.indent) 1617 | } 1618 | 1619 | #[inline] 1620 | fn begin_object_value(&mut self, writer: &mut W) -> io::Result<()> 1621 | where 1622 | W: io::Write, 1623 | { 1624 | writer.write_all(b": ") 1625 | } 1626 | 1627 | #[inline] 1628 | fn end_object_value(&mut self, _writer: &mut W) -> io::Result<()> 1629 | where 1630 | W: io::Write, 1631 | { 1632 | self.has_value = true; 1633 | Ok(()) 1634 | } 1635 | } 1636 | 1637 | fn format_escaped_str( 1638 | writer: &mut W, 1639 | formatter: &mut F, 1640 | value: &str, 1641 | ) -> io::Result<()> 1642 | where 1643 | W: io::Write, 1644 | F: Formatter, 1645 | { 1646 | try!(formatter.begin_string(writer)); 1647 | try!(format_escaped_str_contents(writer, formatter, value)); 1648 | try!(formatter.end_string(writer)); 1649 | Ok(()) 1650 | } 1651 | 1652 | fn format_escaped_str_contents( 1653 | writer: &mut W, 1654 | formatter: &mut F, 1655 | value: &str, 1656 | ) -> io::Result<()> 1657 | where 1658 | W: io::Write, 1659 | F: Formatter, 1660 | { 1661 | let bytes = value.as_bytes(); 1662 | 1663 | let mut start = 0; 1664 | 1665 | for (i, &byte) in bytes.iter().enumerate() { 1666 | let escape = ESCAPE[byte as usize]; 1667 | if escape == 0 { 1668 | continue; 1669 | } 1670 | 1671 | if start < i { 1672 | try!(formatter.write_string_fragment(writer, &value[start..i])); 1673 | } 1674 | 1675 | let char_escape = CharEscape::from_escape_table(escape, byte); 1676 | try!(formatter.write_char_escape(writer, char_escape)); 1677 | 1678 | start = i + 1; 1679 | } 1680 | 1681 | if start != bytes.len() { 1682 | try!(formatter.write_string_fragment(writer, &value[start..])); 1683 | } 1684 | 1685 | Ok(()) 1686 | } 1687 | 1688 | const BB: u8 = b'b'; // \x08 1689 | const TT: u8 = b't'; // \x09 1690 | const NN: u8 = b'n'; // \x0A 1691 | const FF: u8 = b'f'; // \x0C 1692 | const RR: u8 = b'r'; // \x0D 1693 | const QU: u8 = b'"'; // \x22 1694 | const BS: u8 = b'\\'; // \x5C 1695 | const U: u8 = b'u'; // \x00...\x1F except the ones above 1696 | 1697 | // Lookup table of escape sequences. A value of b'x' at index i means that byte 1698 | // i is escaped as "\x" in S-expression. A value of 0 means that byte i is not escaped. 1699 | #[cfg_attr(rustfmt, rustfmt_skip)] 1700 | static ESCAPE: [u8; 256] = [ 1701 | // 1 2 3 4 5 6 7 8 9 A B C D E F 1702 | U, U, U, U, U, U, U, U, BB, TT, NN, U, FF, RR, U, U, // 0 1703 | U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, U, // 1 1704 | 0, 0, QU, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2 1705 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3 1706 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4 1707 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, BS, 0, 0, 0, // 5 1708 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6 1709 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7 1710 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8 1711 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9 1712 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A 1713 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B 1714 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C 1715 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D 1716 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E 1717 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // F 1718 | ]; 1719 | 1720 | #[inline] 1721 | fn format_escaped_char( 1722 | wr: &mut W, 1723 | formatter: &mut F, 1724 | value: char, 1725 | ) -> io::Result<()> 1726 | where 1727 | W: io::Write, 1728 | F: Formatter, 1729 | { 1730 | use std::io::Write; 1731 | // A char encoded as UTF-8 takes 4 bytes at most. 1732 | let mut buf = [0; 4]; 1733 | write!(&mut buf[..], "{}", value).expect("write char to 4-byte buffer"); 1734 | // Writing a char successfully always produce valid UTF-8. 1735 | // Once we do not support Rust <1.15 we will be able to just use 1736 | // the method `char::encode_utf8`. 1737 | // See https://github.com/serde-rs/json/issues/270. 1738 | let slice = unsafe { str::from_utf8_unchecked(&buf[0..value.len_utf8()]) }; 1739 | format_escaped_str(wr, formatter, slice) 1740 | } 1741 | 1742 | /// Serialize the given data structure as S-expression into the IO stream. 1743 | /// 1744 | /// # Errors 1745 | /// 1746 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1747 | /// fail, or if `T` contains a map with non-string keys. 1748 | #[inline] 1749 | pub fn to_writer(writer: W, value: &T) -> Result<()> 1750 | where 1751 | W: io::Write, 1752 | T: ser::Serialize, 1753 | { 1754 | let mut ser = Serializer::new(writer); 1755 | try!(value.serialize(&mut ser)); 1756 | Ok(()) 1757 | } 1758 | 1759 | /// Serialize the given data structure as pretty-printed S-expression into the IO 1760 | /// stream. 1761 | /// 1762 | /// # Errors 1763 | /// 1764 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1765 | /// fail, or if `T` contains a map with non-string keys. 1766 | #[inline] 1767 | pub fn to_writer_pretty(writer: W, value: &T) -> Result<()> 1768 | where 1769 | W: io::Write, 1770 | T: ser::Serialize, 1771 | { 1772 | let mut ser = Serializer::pretty(writer); 1773 | try!(value.serialize(&mut ser)); 1774 | Ok(()) 1775 | } 1776 | 1777 | /// Serialize the given data structure as a S-expression byte vector. 1778 | /// 1779 | /// # Errors 1780 | /// 1781 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1782 | /// fail, or if `T` contains a map with non-string keys. 1783 | #[inline] 1784 | pub fn to_vec(value: &T) -> Result> 1785 | where 1786 | T: ser::Serialize, 1787 | { 1788 | let mut writer = Vec::with_capacity(128); 1789 | try!(to_writer(&mut writer, value)); 1790 | Ok(writer) 1791 | } 1792 | 1793 | /// Serialize the given data structure as a pretty-printed S-expression byte vector. 1794 | /// 1795 | /// # Errors 1796 | /// 1797 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1798 | /// fail, or if `T` contains a map with non-string keys. 1799 | #[inline] 1800 | pub fn to_vec_pretty(value: &T) -> Result> 1801 | where 1802 | T: ser::Serialize, 1803 | { 1804 | let mut writer = Vec::with_capacity(128); 1805 | try!(to_writer_pretty(&mut writer, value)); 1806 | Ok(writer) 1807 | } 1808 | 1809 | /// Serialize the given data structure as a String of S-expression. 1810 | /// 1811 | /// # Errors 1812 | /// 1813 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1814 | /// fail, or if `T` contains a map with non-string keys. 1815 | #[inline] 1816 | pub fn to_string(value: &T) -> Result 1817 | where 1818 | T: ser::Serialize, 1819 | { 1820 | let vec = try!(to_vec(value)); 1821 | let string = unsafe { 1822 | // We do not emit invalid UTF-8. 1823 | String::from_utf8_unchecked(vec) 1824 | }; 1825 | Ok(string) 1826 | } 1827 | 1828 | /// Serialize the given data structure as a pretty-printed String of S-expression. 1829 | /// 1830 | /// # Errors 1831 | /// 1832 | /// Serialization can fail if `T`'s implementation of `Serialize` decides to 1833 | /// fail, or if `T` contains a map with non-string keys. 1834 | #[inline] 1835 | pub fn to_string_pretty(value: &T) -> Result 1836 | where 1837 | T: ser::Serialize, 1838 | { 1839 | let vec = try!(to_vec_pretty(value)); 1840 | let string = unsafe { 1841 | // We do not emit invalid UTF-8. 1842 | String::from_utf8_unchecked(vec) 1843 | }; 1844 | Ok(string) 1845 | } 1846 | 1847 | fn indent(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()> 1848 | where 1849 | W: io::Write, 1850 | { 1851 | for _ in 0..n { 1852 | try!(wr.write_all(s)); 1853 | } 1854 | 1855 | Ok(()) 1856 | } 1857 | -------------------------------------------------------------------------------- /src/sexp/de.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use std::fmt; 10 | use std::i64; 11 | use std::io; 12 | use std::slice; 13 | use std::str; 14 | use std::vec; 15 | 16 | use serde; 17 | use serde::de::{ 18 | Deserialize, 19 | DeserializeSeed, 20 | Visitor, 21 | SeqAccess, 22 | MapAccess, 23 | }; 24 | 25 | use error::Error; 26 | use number::Number; 27 | use atom::Atom; 28 | use sexp::Sexp; 29 | 30 | impl<'de> Deserialize<'de> for Sexp { 31 | #[inline] 32 | fn deserialize(deserializer: D) -> Result 33 | where 34 | D: serde::Deserializer<'de>, 35 | { 36 | struct ValueVisitor; 37 | 38 | impl<'de> Visitor<'de> for ValueVisitor { 39 | type Value = Sexp; 40 | 41 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 42 | formatter.write_str("any valid Sexp value") 43 | } 44 | 45 | #[inline] 46 | fn visit_bool(self, value: bool) -> Result { 47 | Ok(Sexp::Boolean(value)) 48 | } 49 | 50 | #[inline] 51 | fn visit_i64(self, value: i64) -> Result { 52 | Ok(Sexp::Number(value.into())) 53 | } 54 | 55 | #[inline] 56 | fn visit_u64(self, value: u64) -> Result { 57 | Ok(Sexp::Number(value.into())) 58 | } 59 | 60 | #[inline] 61 | fn visit_f64(self, value: f64) -> Result { 62 | Ok(Number::from_f64(value).map_or(Sexp::Nil, Sexp::Number)) 63 | } 64 | 65 | #[inline] 66 | fn visit_str(self, value: &str) -> Result 67 | where 68 | E: serde::de::Error, 69 | { 70 | self.visit_string(String::from(value)) 71 | } 72 | 73 | #[inline] 74 | fn visit_string(self, value: String) -> Result { 75 | Ok(Sexp::Atom(Atom::into_string(value))) 76 | } 77 | 78 | #[inline] 79 | fn visit_none(self) -> Result { 80 | Ok(Sexp::Nil) 81 | } 82 | 83 | #[inline] 84 | fn visit_some(self, deserializer: D) -> Result 85 | where 86 | D: serde::Deserializer<'de>, 87 | { 88 | Deserialize::deserialize(deserializer) 89 | } 90 | 91 | #[inline] 92 | fn visit_unit(self) -> Result { 93 | Ok(Sexp::Nil) 94 | } 95 | 96 | #[inline] 97 | fn visit_newtype_struct(self, deserializer: D) -> Result 98 | where 99 | D: serde::Deserializer<'de>, 100 | { 101 | /// XXX something about this feels wrong 102 | let result: String = try!(Deserialize::deserialize(deserializer)); 103 | Ok(Sexp::Atom(Atom::into_symbol(String::from(result)))) 104 | } 105 | 106 | 107 | #[inline] 108 | fn visit_seq(self, mut visitor: V) -> Result 109 | where 110 | V: SeqAccess<'de>, 111 | { 112 | let mut vec = Vec::new(); 113 | 114 | while let Some(elem) = try!(visitor.next_element()) { 115 | vec.push(elem); 116 | } 117 | 118 | Ok(Sexp::List(vec)) 119 | } 120 | 121 | fn visit_map(self, _visitor: V) -> Result 122 | where 123 | V: MapAccess<'de>, 124 | { 125 | unimplemented!() 126 | } 127 | } 128 | 129 | deserializer.deserialize_any(ValueVisitor) 130 | } 131 | } 132 | 133 | struct WriterFormatter<'a, 'b: 'a> { 134 | inner: &'a mut fmt::Formatter<'b>, 135 | } 136 | 137 | impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> { 138 | fn write(&mut self, buf: &[u8]) -> io::Result { 139 | fn io_error(_: E) -> io::Error { 140 | // Sexp does not matter because fmt::Debug and fmt::Display impls 141 | // below just map it to fmt::Error 142 | io::Error::new(io::ErrorKind::Other, "fmt error") 143 | } 144 | let s = try!(str::from_utf8(buf).map_err(io_error)); 145 | try!(self.inner.write_str(s).map_err(io_error)); 146 | Ok(buf.len()) 147 | } 148 | 149 | fn flush(&mut self) -> io::Result<()> { 150 | Ok(()) 151 | } 152 | } 153 | 154 | 155 | impl fmt::Display for Sexp { 156 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 157 | let alternate = f.alternate(); 158 | let mut wr = WriterFormatter { inner: f }; 159 | if alternate { 160 | // {:#} 161 | super::super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error) 162 | } else { 163 | // {} 164 | super::super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error) 165 | } 166 | } 167 | } 168 | 169 | 170 | impl str::FromStr for Sexp { 171 | type Err = Error; 172 | fn from_str(s: &str) -> Result { 173 | super::super::de::from_str(s) 174 | } 175 | } 176 | 177 | impl<'de> serde::Deserializer<'de> for Sexp { 178 | type Error = Error; 179 | 180 | #[inline] 181 | fn deserialize_any(self, visitor: V) -> Result 182 | where 183 | V: Visitor<'de>, 184 | { 185 | match self { 186 | Sexp::Nil => visitor.visit_unit(), 187 | Sexp::Boolean(v) => visitor.visit_bool(v), 188 | Sexp::Number(n) => n.deserialize_any(visitor), 189 | Sexp::Atom(a) => visitor.visit_string(a.as_string()), 190 | Sexp::Pair(_, _) => { 191 | unimplemented!() 192 | }, 193 | Sexp::List(v) => { 194 | let len = v.len(); 195 | let mut deserializer = SeqDeserializer::new(v); 196 | let seq = try!(visitor.visit_seq(&mut deserializer)); 197 | let remaining = deserializer.iter.len(); 198 | if remaining == 0 { 199 | Ok(seq) 200 | } else { 201 | Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) 202 | } 203 | } 204 | } 205 | } 206 | 207 | #[inline] 208 | fn deserialize_option(self, visitor: V) -> Result 209 | where 210 | V: Visitor<'de>, 211 | { 212 | match self { 213 | Sexp::Nil => visitor.visit_none(), 214 | _ => visitor.visit_some(self), 215 | } 216 | } 217 | 218 | #[inline] 219 | fn deserialize_enum( 220 | self, 221 | _name: &str, 222 | _variants: &'static [&'static str], 223 | _visitor: V, 224 | ) -> Result 225 | where 226 | V: Visitor<'de>, 227 | { 228 | unimplemented!() 229 | } 230 | 231 | #[inline] 232 | fn deserialize_newtype_struct( 233 | self, 234 | _name: &'static str, 235 | visitor: V, 236 | ) -> Result 237 | where 238 | V: Visitor<'de>, 239 | { 240 | visitor.visit_newtype_struct(self) 241 | } 242 | 243 | forward_to_deserialize_any! { 244 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 245 | byte_buf unit unit_struct seq tuple tuple_struct map struct identifier 246 | ignored_any 247 | } 248 | } 249 | 250 | struct SeqDeserializer { 251 | iter: vec::IntoIter, 252 | } 253 | 254 | impl SeqDeserializer { 255 | fn new(vec: Vec) -> Self { 256 | SeqDeserializer { iter: vec.into_iter() } 257 | } 258 | } 259 | 260 | impl<'de> serde::Deserializer<'de> for SeqDeserializer { 261 | type Error = Error; 262 | 263 | #[inline] 264 | fn deserialize_any(mut self, visitor: V) -> Result 265 | where 266 | V: Visitor<'de>, 267 | { 268 | let len = self.iter.len(); 269 | if len == 0 { 270 | visitor.visit_unit() 271 | } else { 272 | let ret = try!(visitor.visit_seq(&mut self)); 273 | let remaining = self.iter.len(); 274 | if remaining == 0 { 275 | Ok(ret) 276 | } else { 277 | Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) 278 | } 279 | } 280 | } 281 | 282 | forward_to_deserialize_any! { 283 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 284 | byte_buf option unit unit_struct newtype_struct seq tuple 285 | tuple_struct map struct enum identifier ignored_any 286 | } 287 | } 288 | 289 | impl<'de> SeqAccess<'de> for SeqDeserializer { 290 | type Error = Error; 291 | 292 | fn next_element_seed(&mut self, seed: T) -> Result, Error> 293 | where 294 | T: DeserializeSeed<'de>, 295 | { 296 | match self.iter.next() { 297 | Some(value) => seed.deserialize(value).map(Some), 298 | None => Ok(None), 299 | } 300 | } 301 | 302 | fn size_hint(&self) -> Option { 303 | match self.iter.size_hint() { 304 | (lower, Some(upper)) if lower == upper => Some(upper), 305 | _ => None, 306 | } 307 | } 308 | } 309 | 310 | 311 | impl<'de> serde::Deserializer<'de> for &'de Sexp { 312 | type Error = Error; 313 | 314 | fn deserialize_any(self, visitor: V) -> Result 315 | where 316 | V: Visitor<'de>, 317 | { 318 | match *self { 319 | Sexp::Nil => visitor.visit_unit(), 320 | Sexp::Boolean(v) => visitor.visit_bool(v), 321 | Sexp::Number(ref n) => n.deserialize_any(visitor), 322 | Sexp::Atom(ref a) => visitor.visit_borrowed_str(a.as_str()), 323 | Sexp::Pair(_, _) => { 324 | unimplemented!() 325 | }, 326 | Sexp::List(ref v) => { 327 | let len = v.len(); 328 | let mut deserializer = SeqRefDeserializer::new(v); 329 | let seq = try!(visitor.visit_seq(&mut deserializer)); 330 | let remaining = deserializer.iter.len(); 331 | if remaining == 0 { 332 | Ok(seq) 333 | } else { 334 | Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) 335 | } 336 | } 337 | } 338 | } 339 | 340 | fn deserialize_option(self, visitor: V) -> Result 341 | where 342 | V: Visitor<'de>, 343 | { 344 | match *self { 345 | Sexp::Nil => visitor.visit_none(), 346 | _ => visitor.visit_some(self), 347 | } 348 | } 349 | 350 | fn deserialize_enum( 351 | self, 352 | _name: &str, 353 | _variants: &'static [&'static str], 354 | _visitor: V, 355 | ) -> Result 356 | where 357 | V: Visitor<'de>, 358 | { 359 | unimplemented!() 360 | } 361 | 362 | #[inline] 363 | fn deserialize_newtype_struct( 364 | self, 365 | _name: &'static str, 366 | visitor: V, 367 | ) -> Result 368 | where 369 | V: Visitor<'de>, 370 | { 371 | visitor.visit_newtype_struct(self) 372 | } 373 | 374 | forward_to_deserialize_any! { 375 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 376 | byte_buf unit unit_struct seq tuple tuple_struct map struct identifier 377 | ignored_any 378 | } 379 | } 380 | 381 | 382 | struct SeqRefDeserializer<'de> { 383 | iter: slice::Iter<'de, Sexp>, 384 | } 385 | 386 | impl<'de> SeqRefDeserializer<'de> { 387 | fn new(slice: &'de [Sexp]) -> Self { 388 | SeqRefDeserializer { iter: slice.iter() } 389 | } 390 | } 391 | 392 | impl<'de> serde::Deserializer<'de> for SeqRefDeserializer<'de> { 393 | type Error = Error; 394 | 395 | #[inline] 396 | fn deserialize_any(mut self, visitor: V) -> Result 397 | where 398 | V: Visitor<'de>, 399 | { 400 | let len = self.iter.len(); 401 | if len == 0 { 402 | visitor.visit_unit() 403 | } else { 404 | let ret = try!(visitor.visit_seq(&mut self)); 405 | let remaining = self.iter.len(); 406 | if remaining == 0 { 407 | Ok(ret) 408 | } else { 409 | Err(serde::de::Error::invalid_length(len, &"fewer elements in array")) 410 | } 411 | } 412 | } 413 | 414 | forward_to_deserialize_any! { 415 | bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes 416 | byte_buf option unit unit_struct newtype_struct seq tuple 417 | tuple_struct map struct enum identifier ignored_any 418 | } 419 | } 420 | 421 | impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> { 422 | type Error = Error; 423 | 424 | fn next_element_seed(&mut self, seed: T) -> Result, Error> 425 | where 426 | T: DeserializeSeed<'de>, 427 | { 428 | match self.iter.next() { 429 | Some(value) => seed.deserialize(value).map(Some), 430 | None => Ok(None), 431 | } 432 | } 433 | 434 | fn size_hint(&self) -> Option { 435 | match self.iter.size_hint() { 436 | (lower, Some(upper)) if lower == upper => Some(upper), 437 | _ => None, 438 | } 439 | } 440 | } 441 | 442 | -------------------------------------------------------------------------------- /src/sexp/from.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use std::borrow::Cow; 10 | 11 | use super::Sexp; 12 | use map::Map; 13 | use number::Number; 14 | 15 | macro_rules! from_integer { 16 | ($($ty:ident)*) => { 17 | $( 18 | impl From<$ty> for Sexp { 19 | fn from(n: $ty) -> Self { 20 | Sexp::Number(n.into()) 21 | } 22 | } 23 | )* 24 | }; 25 | } 26 | 27 | from_integer! { 28 | i8 i16 i32 i64 isize 29 | u8 u16 u32 u64 usize 30 | } 31 | 32 | impl From for Sexp { 33 | /// Convert 32-bit floating point number to `Sexp` 34 | /// 35 | /// # Examples 36 | /// 37 | /// ```rust,ignore 38 | /// # extern crate sexpr; 39 | /// # 40 | /// # fn main() { 41 | /// use sexpr::Sexp; 42 | /// 43 | /// let f: f32 = 13.37; 44 | /// let x: Sexp = f.into(); 45 | /// # } 46 | /// ``` 47 | fn from(f: f32) -> Self { 48 | From::from(f as f64) 49 | } 50 | } 51 | 52 | impl From for Sexp { 53 | /// Convert 64-bit floating point number to `Sexp` 54 | /// 55 | /// # Examples 56 | /// 57 | /// ```rust,ignore 58 | /// # extern crate sexpr; 59 | /// # 60 | /// # fn main() { 61 | /// use sexpr::Sexp; 62 | /// 63 | /// let f: f64 = 13.37; 64 | /// let x: Sexp = f.into(); 65 | /// # } 66 | /// ``` 67 | fn from(f: f64) -> Self { 68 | Number::from_f64(f).map_or(Sexp::Null, Sexp::Number) 69 | } 70 | } 71 | 72 | impl From for Sexp { 73 | /// Convert boolean to `Sexp` 74 | /// 75 | /// # Examples 76 | /// 77 | /// ```rust,ignore 78 | /// # extern crate sexpr; 79 | /// # 80 | /// # fn main() { 81 | /// use sexpr::Sexp; 82 | /// 83 | /// let b = false; 84 | /// let x: Sexp = b.into(); 85 | /// # } 86 | /// ``` 87 | fn from(f: bool) -> Self { 88 | Sexp::Boolean(f) 89 | } 90 | } 91 | 92 | impl From for Sexp { 93 | /// Convert `String` to `Sexp` 94 | /// 95 | /// # Examples 96 | /// 97 | /// ```rust,ignore 98 | /// # extern crate sexpr; 99 | /// # 100 | /// # fn main() { 101 | /// use sexpr::Sexp; 102 | /// 103 | /// let s: String = "lorem".to_string(); 104 | /// let x: Sexp = s.into(); 105 | /// # } 106 | /// ``` 107 | fn from(f: String) -> Self { 108 | Sexp::Atom(Atom::from_string(f)) 109 | } 110 | } 111 | 112 | impl<'a> From<&'a str> for Sexp { 113 | /// Convert string slice to `Sexp` 114 | /// 115 | /// # Examples 116 | /// 117 | /// ```rust,ignore 118 | /// # extern crate sexpr; 119 | /// # 120 | /// # fn main() { 121 | /// use sexpr::Sexp; 122 | /// 123 | /// let s: &str = "lorem"; 124 | /// let x: Sexp = s.into(); 125 | /// # } 126 | /// ``` 127 | fn from(f: &str) -> Self { 128 | Sexp::Atom(Atom::from_str(f)) 129 | } 130 | } 131 | 132 | impl<'a> From> for Sexp { 133 | /// Convert copy-on-write string to `Sexp` 134 | /// 135 | /// # Examples 136 | /// 137 | /// ```rust,ignore 138 | /// # extern crate sexpr; 139 | /// # 140 | /// # fn main() { 141 | /// use sexpr::Sexp; 142 | /// use std::borrow::Cow; 143 | /// 144 | /// let s: Cow = Cow::Borrowed("lorem"); 145 | /// let x: Sexp = s.into(); 146 | /// # } 147 | /// ``` 148 | /// 149 | /// ```rust,ignore 150 | /// # extern crate sexpr; 151 | /// # 152 | /// # fn main() { 153 | /// use sexpr::Sexp; 154 | /// use std::borrow::Cow; 155 | /// 156 | /// let s: Cow = Cow::Owned("lorem".to_string()); 157 | /// let x: Sexp = s.into(); 158 | /// # } 159 | /// ``` 160 | fn from(f: Cow<'a, str>) -> Self { 161 | Sexp::Atom(Atom::from_string(f)) 162 | } 163 | } 164 | 165 | impl From> for Sexp { 166 | /// Convert map (with string keys) to `Sexp` 167 | /// 168 | /// # Examples 169 | /// 170 | /// ```rust,ignore 171 | /// # extern crate sexpr; 172 | /// # 173 | /// # fn main() { 174 | /// use sexpr::{Map, Sexp}; 175 | /// 176 | /// let mut m = Map::new(); 177 | /// m.insert("Lorem".to_string(), "ipsum".into()); 178 | /// let x: Sexp = m.into(); 179 | /// # } 180 | /// ``` 181 | fn from(f: Map) -> Self { 182 | unimplemented!() 183 | } 184 | } 185 | 186 | impl> From> for Sexp { 187 | /// Convert a `Vec` to `Sexp` 188 | /// 189 | /// # Examples 190 | /// 191 | /// ```rust,ignore 192 | /// # extern crate sexpr; 193 | /// # 194 | /// # fn main() { 195 | /// use sexpr::Sexp; 196 | /// 197 | /// let v = vec!["lorem", "ipsum", "dolor"]; 198 | /// let x: Sexp = v.into(); 199 | /// # } 200 | /// ``` 201 | fn from(f: Vec) -> Self { 202 | Sexp::List(f.into_iter().map(Into::into).collect()) 203 | } 204 | } 205 | 206 | impl<'a, T: Clone + Into> From<&'a [T]> for Sexp { 207 | /// Convert a slice to `Sexp` 208 | /// 209 | /// # Examples 210 | /// 211 | /// ```rust,ignore 212 | /// # extern crate sexpr; 213 | /// # 214 | /// # fn main() { 215 | /// use sexpr::Sexp; 216 | /// 217 | /// let v: &[&str] = &["lorem", "ipsum", "dolor"]; 218 | /// let x: Sexp = v.into(); 219 | /// # } 220 | /// ``` 221 | fn from(f: &'a [T]) -> Self { 222 | Sexp::List(f.into_iter().cloned().map(Into::into).collect()) 223 | } 224 | } 225 | 226 | impl> ::std::iter::FromIterator for Sexp { 227 | /// Convert an iteratable type to a `Sexp` 228 | /// 229 | /// # Examples 230 | /// 231 | /// ```rust,ignore 232 | /// # extern crate sexpr; 233 | /// # 234 | /// # fn main() { 235 | /// use sexpr::Sexp; 236 | /// 237 | /// let v = std::iter::repeat(42).take(5); 238 | /// let x: Sexp = v.collect(); 239 | /// # } 240 | /// ``` 241 | /// 242 | /// ```rust,ignore 243 | /// # extern crate sexpr; 244 | /// # 245 | /// # fn main() { 246 | /// use sexpr::Sexp; 247 | /// 248 | /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"]; 249 | /// let x: Sexp = v.into_iter().collect(); 250 | /// # } 251 | /// ``` 252 | /// 253 | /// ```rust,ignore 254 | /// # extern crate sexpr; 255 | /// # 256 | /// # fn main() { 257 | /// use std::iter::FromIterator; 258 | /// use sexpr::Sexp; 259 | /// 260 | /// let x: Sexp = Sexp::from_iter(vec!["lorem", "ipsum", "dolor"]); 261 | /// # } 262 | /// ``` 263 | fn from_iter>(iter: I) -> Self { 264 | let vec: Vec = iter.into_iter().map(|x| x.into()).collect(); 265 | 266 | Sexp::List(vec) 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /src/sexp/index.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use std::fmt; 10 | use std::ops; 11 | 12 | use super::Sexp; 13 | 14 | /// A type that can be used to index into a `sexpr::Sexp`. See the `get` 15 | /// and `get_mut` methods of `Sexp`. 16 | /// 17 | /// This trait is sealed and cannot be implemented for types outside of 18 | /// `sexpr`. 19 | pub trait Index: private::Sealed { 20 | /// Return None if the key is not already in the array or object. 21 | #[doc(hidden)] 22 | fn index_into<'v>(&self, v: &'v Sexp) -> Option<&'v Sexp>; 23 | 24 | /// Return None if the key is not already in the array or object. 25 | #[doc(hidden)] 26 | fn index_into_mut<'v>(&self, v: &'v mut Sexp) -> Option<&'v mut Sexp>; 27 | 28 | /// Panic if array index out of bounds. If key is not already in the object, 29 | /// insert it with a value of null. Panic if Sexp is a type that cannot be 30 | /// indexed into, except if Sexp is null then it can be treated as an empty 31 | /// object. 32 | #[doc(hidden)] 33 | fn index_or_insert<'v>(&self, v: &'v mut Sexp) -> &'v mut Sexp; 34 | } 35 | 36 | impl Index for usize { 37 | fn index_into<'v>(&self, v: &'v Sexp) -> Option<&'v Sexp> { 38 | match *v { 39 | Sexp::List(ref vec) => vec.get(*self), 40 | _ => None, 41 | } 42 | } 43 | fn index_into_mut<'v>(&self, v: &'v mut Sexp) -> Option<&'v mut Sexp> { 44 | match *v { 45 | Sexp::List(ref mut vec) => vec.get_mut(*self), 46 | _ => None, 47 | } 48 | } 49 | fn index_or_insert<'v>(&self, v: &'v mut Sexp) -> &'v mut Sexp { 50 | match *v { 51 | Sexp::List(ref mut vec) => { 52 | let len = vec.len(); 53 | vec.get_mut(*self) 54 | .unwrap_or_else( 55 | || { 56 | panic!( 57 | "cannot access index {} of JSON array of length {}", 58 | self, 59 | len 60 | ) 61 | }, 62 | ) 63 | } 64 | _ => panic!("cannot access index {} of JSON {}", self, Type(v)), 65 | } 66 | } 67 | } 68 | 69 | impl Index for str { 70 | fn index_into<'v>(&self, v: &'v Sexp) -> Option<&'v Sexp> { 71 | match v { 72 | &Sexp::List(_) => v.get(self), 73 | _ => None, 74 | } 75 | } 76 | fn index_into_mut<'v>(&self, _v: &'v mut Sexp) -> Option<&'v mut Sexp> { 77 | unimplemented!() 78 | } 79 | fn index_or_insert<'v>(&self, _v: &'v mut Sexp) -> &'v mut Sexp { 80 | unimplemented!() 81 | } 82 | } 83 | 84 | impl Index for String { 85 | fn index_into<'v>(&self, v: &'v Sexp) -> Option<&'v Sexp> { 86 | self[..].index_into(v) 87 | } 88 | fn index_into_mut<'v>(&self, v: &'v mut Sexp) -> Option<&'v mut Sexp> { 89 | self[..].index_into_mut(v) 90 | } 91 | fn index_or_insert<'v>(&self, v: &'v mut Sexp) -> &'v mut Sexp { 92 | self[..].index_or_insert(v) 93 | } 94 | } 95 | 96 | impl<'a, T: ?Sized> Index for &'a T 97 | where 98 | T: Index, 99 | { 100 | fn index_into<'v>(&self, v: &'v Sexp) -> Option<&'v Sexp> { 101 | (**self).index_into(v) 102 | } 103 | fn index_into_mut<'v>(&self, v: &'v mut Sexp) -> Option<&'v mut Sexp> { 104 | (**self).index_into_mut(v) 105 | } 106 | fn index_or_insert<'v>(&self, v: &'v mut Sexp) -> &'v mut Sexp { 107 | (**self).index_or_insert(v) 108 | } 109 | } 110 | 111 | // Prevent users from implementing the Index trait. 112 | mod private { 113 | pub trait Sealed {} 114 | impl Sealed for usize {} 115 | impl Sealed for str {} 116 | impl Sealed for String {} 117 | impl<'a, T: ?Sized> Sealed for &'a T 118 | where 119 | T: Sealed, 120 | { 121 | } 122 | } 123 | 124 | /// Used in panic messages. 125 | struct Type<'a>(&'a Sexp); 126 | 127 | impl<'a> fmt::Display for Type<'a> { 128 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 129 | match *self.0 { 130 | Sexp::Nil => formatter.write_str("nil"), 131 | Sexp::Boolean(_) => formatter.write_str("boolean"), 132 | Sexp::Number(_) => formatter.write_str("number"), 133 | Sexp::Atom(_) => formatter.write_str("atom"), 134 | Sexp::List(_) => formatter.write_str("list"), 135 | Sexp::Pair(_, _) => formatter.write_str("pair"), 136 | } 137 | } 138 | } 139 | 140 | // The usual semantics of Index is to panic on invalid indexing. 141 | // 142 | // That said, the usual semantics are for things like Vec and BTreeMap which 143 | // have different use cases than Sexp. If you are working with a Vec, you know 144 | // that you are working with a Vec and you can get the len of the Vec and make 145 | // sure your indices are within bounds. The Sexp use cases are more 146 | // loosey-goosey. You got some sexprs from an endpoint and you want to pull values 147 | // out of it. Outside of this Index impl, you already have the option of using 148 | // value.as_array() and working with the Vec directly, or matching on 149 | // Sexp::List and getting the Vec directly. The Index impl means you can skip 150 | // that and index directly into the thing using a concise syntax. You don't have 151 | // to check the type, you don't have to check the len, it is all about what you 152 | // expect the Sexp to look like. 153 | // 154 | // Basically the use cases that would be well served by panicking here are 155 | // better served by using one of the other approaches: get and get_mut, 156 | // as_array, or match. The value of this impl is that it adds a way of working 157 | // with Sexp that is not well served by the existing approaches: concise and 158 | // careless and sometimes that is exactly what you want. 159 | impl ops::Index for Sexp 160 | where 161 | I: Index, 162 | { 163 | type Output = Sexp; 164 | 165 | /// Index into a `sexpr::Sexp` using the syntax `value[0]` or 166 | /// `value["k"]`. 167 | /// 168 | /// Returns `Sexp::Nil` if the type of `self` does not match the type of 169 | /// the index, for example if the index is a string and `self` is an array 170 | /// or a number. Also returns `Sexp::Nil` if the given key does not exist 171 | /// in the map or the given index is not within the bounds of the array. 172 | /// 173 | /// For retrieving deeply nested values, you should have a look at the 174 | /// `Sexp::pointer` method. 175 | /// 176 | /// # Examples 177 | /// 178 | /// ```rust,ignore 179 | /// # #[macro_use] 180 | /// # extern crate sexpr; 181 | /// # 182 | /// # fn main() { 183 | /// let data = sexpr::from_str("(x . (y . (z zz)))") 184 | /// 185 | /// assert_eq!(data["x"]["y"], sexpr::from_str("(z zz)")); 186 | /// assert_eq!(data["x"]["y"][0], sexpr::from_str("z")); 187 | /// 188 | /// assert_eq!(data["a"], Sexp::Nil); // returns null for undefined values 189 | /// assert_eq!(data["a"]["b"], Sexp::Nil); // does not panic 190 | /// # } 191 | /// ``` 192 | fn index(&self, index: I) -> &Sexp { 193 | static NIL: Sexp = Sexp::Nil; 194 | index.index_into(self).unwrap_or(&NIL) 195 | } 196 | } 197 | 198 | impl ops::IndexMut for Sexp 199 | where 200 | I: Index, 201 | { 202 | /// Write into a `sexpr::Sexp` using the syntax `value[0] = ...` or 203 | /// `value["k"] = ...`. 204 | /// 205 | /// If the index is a number, the value must be an array of length bigger 206 | /// than the index. Indexing into a value that is not an array or an array 207 | /// that is too small will panic. 208 | /// 209 | /// If the index is a string, the value must be an object or null which is 210 | /// treated like an empty object. If the key is not already present in the 211 | /// object, it will be inserted with a value of null. Indexing into a value 212 | /// that is neither an object nor null will panic. 213 | /// 214 | /// # Examples 215 | /// 216 | /// ```rust,ignore 217 | /// # #[macro_use] 218 | /// # extern crate sexpr; 219 | /// # 220 | /// # fn main() { 221 | /// let mut data = sexp!((x . 0)); 222 | /// 223 | /// // replace an existing key 224 | /// data["x"] = sexp!(1); 225 | /// 226 | /// // insert a new key 227 | /// data["y"] = sexp!((#f #f #f)); 228 | /// 229 | /// // replace an array value 230 | /// data["y"][0] = sexp!(#f); 231 | /// 232 | /// // inserted a deeply nested key 233 | /// data["a"]["b"]["c"]["d"] = sexp!(#t); 234 | /// 235 | /// println!("{}", data); 236 | /// # } 237 | /// ``` 238 | fn index_mut(&mut self, index: I) -> &mut Sexp { 239 | index.index_or_insert(self) 240 | } 241 | } 242 | -------------------------------------------------------------------------------- /src/sexp/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr "zv" Pellerin. See the COPYRIGHT 2 | // file at the top-level directory of this distribution 3 | // 4 | // Licensed under the MIT License, , at your option. This file may not be 6 | // copied, modified, or distributed except according to those terms. 7 | 8 | //! The Sexp enum, a loosely typed way of representing any valid S-expression value. 9 | //! 10 | //! # Constructing S-expression 11 | //! 12 | //! Serde S-expression provides a [`sexp!` macro][macro] to build `sexpr::Sexp` 13 | //! objects with very natural S-expression syntax. In order to use this macro, 14 | //! `sexpr` needs to be imported with the `#[macro_use]` attribute. 15 | //! 16 | //! ```rust,ignore 17 | //! #[macro_use] 18 | //! extern crate sexpr; 19 | //! 20 | //! fn main() { 21 | //! // The type of `john` is `sexpr::Sexp` 22 | //! let john = sexp!(( 23 | //! ("name" . "John Doe") 24 | //! ("age" . 43) 25 | //! ("phones" . ( 26 | //! ("+44 1234567") 27 | //! ("+44 2345678") 28 | //! )) 29 | //! )); 30 | //! 31 | //! println!("first phone number: {}", john["phones"][0]); 32 | //! 33 | //! // Convert to a string of S-expression and print it out 34 | //! println!("{}", john.to_string()); 35 | //! } 36 | //! ``` 37 | //! 38 | //! The `Sexp::to_string()` function converts a `sexpr::Value` into a `String` of 39 | //! S-expression text. A string of S-expression data can be parsed into a 40 | //! `sexpr::Sexp` by the [`sexpr::from_str`][from_str] function. There is also 41 | //! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and 42 | //! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or a 43 | //! TCP stream. 44 | //! 45 | //! ```rust,ignore 46 | //! extern crate sexpr; 47 | //! 48 | //! use sexpr::{Sexp, Error}; 49 | //! 50 | //! fn untyped_example() -> Result<(), Error> { 51 | //! // Some S-expression input data as a &str. Maybe this comes from the user. 52 | //! let data = r#"( 53 | //! ("name" . "John Doe") 54 | //! ("age" . 43) 55 | //! ("phones" . ( 56 | //! ("+44 1234567") 57 | //! ("+44 2345678") 58 | //! )) 59 | //! )"#; 60 | //! 61 | //! // Parse the string of data into sexpr::Sexp. 62 | //! let v: Sexp = sexpr::from_str(data)?; 63 | //! 64 | //! // Access parts of the data by indexing with square brackets. 65 | //! println!("Please call {} at the number {}", v["name"], v["phones"][0]); 66 | //! 67 | //! Ok(()) 68 | //! } 69 | //! # 70 | //! # fn main() { 71 | //! # untyped_example().unwrap(); 72 | //! # } 73 | //! ``` 74 | //! 75 | use std::str; 76 | use std::string::String; 77 | 78 | use serde::ser::Serialize; 79 | use serde::de::DeserializeOwned; 80 | 81 | use error::Error; 82 | pub use number::Number; 83 | pub use atom::Atom; 84 | 85 | mod index; 86 | pub use self::index::Index; 87 | 88 | use self::ser::Serializer; 89 | 90 | // Rather than having a specialized 'nil' atom, we save space by letting `None` 91 | // here indicates 'nil' 92 | type SexpPtr = Box; 93 | type ConsCell = Option; 94 | 95 | /// Represents any valid S-expression value. 96 | /// 97 | /// See the `sexpr::sexp` module documentation for usage examples. 98 | #[derive(PartialEq, Clone, Debug)] 99 | pub enum Sexp { 100 | /// Represents a S-expression nil value. 101 | /// 102 | /// ```rust,ignore 103 | /// # #[macro_use] 104 | /// # extern crate sexpr; 105 | /// # 106 | /// # fn main() { 107 | /// let v = sexpr!(#nil); 108 | /// # } 109 | /// ``` 110 | Nil, 111 | 112 | /// Represents a S-expression string, symbol or keyword. 113 | /// 114 | /// ```rust,ignore 115 | /// # #[macro_use] 116 | /// # extern crate sexpr; 117 | /// # 118 | /// # fn main() { 119 | /// let s = sexp!("string"); 120 | /// let y = sexp!(symbol); 121 | /// let k = sexp!(#:keyword); 122 | /// # } 123 | /// ``` 124 | Atom(Atom), 125 | 126 | /// Represents a S-expression number, whether integer or floating point. 127 | /// 128 | /// ```rust,ignore 129 | /// # #[macro_use] 130 | /// # extern crate sexpr; 131 | /// # 132 | /// # fn main() { 133 | /// let v = sexp!(12.5); 134 | /// # } 135 | /// ``` 136 | Number(Number), 137 | 138 | /// Represents a S-expression boolean. 139 | /// 140 | /// ```rust,ignore 141 | /// # #[macro_use] 142 | /// # extern crate sexpr; 143 | /// # 144 | /// # fn main() { 145 | /// let v = sexp!(#t); 146 | /// # } 147 | /// ``` 148 | Boolean(bool), 149 | 150 | /// Represents a S-expression cons-pair. 151 | /// 152 | /// ```rust,ignore 153 | /// # #[macro_use] 154 | /// # extern crate sexpr; 155 | /// # 156 | /// # fn main() { 157 | /// let v = sexp!((a . 1)); 158 | /// # } 159 | /// ``` 160 | Pair(ConsCell, ConsCell), 161 | 162 | /// Represents a S-expression list. 163 | /// 164 | /// This enum type is 'multi-function' at this point, possibly representing either 165 | /// a list of items or an associative list. 166 | /// 167 | /// ```rust,ignore 168 | /// # #[macro_use] 169 | /// # extern crate sexpr; 170 | /// # 171 | /// # fn main() { 172 | /// let v = sexp!((a b c)); 173 | /// # } 174 | /// ``` 175 | List(Vec), 176 | } 177 | 178 | mod ser; 179 | mod de; 180 | 181 | 182 | impl From for Sexp { 183 | /// Convert `String` to `Sexp` 184 | /// 185 | /// # Examples 186 | /// 187 | /// ```rust,ignore 188 | /// # extern crate sexpr; 189 | /// # 190 | /// # fn main() { 191 | /// use sexpr::Sexp; 192 | /// 193 | /// let s: String = "lorem".to_string(); 194 | /// let x: Sexp = s.into(); 195 | /// # } 196 | /// ``` 197 | fn from(f: String) -> Self { 198 | Sexp::Atom(Atom::from_string(f)) 199 | } 200 | } 201 | 202 | impl Sexp { 203 | /// Return a new Sexp::Pair with a symbol key 204 | /// 205 | /// # Examples 206 | /// ```rust,ignore 207 | /// # extern crate sexpr; 208 | /// # fn main() { 209 | /// use sexpr::Sexp; 210 | /// let alist_1 = Sexp::new_entry("a", 1) 211 | /// # } 212 | /// ``` 213 | pub fn new_entry, I: Into> (key: A, value: I) -> Sexp { 214 | Sexp::Pair(Some(Box::new(Sexp::Atom(key.into()))), 215 | Some(Box::new(Sexp::from(value.into())))) 216 | } 217 | 218 | /// Index into a Sexp alist or list. A string index can be used to access a 219 | /// value in an alist, and a usize index can be used to access an element of an 220 | /// list. 221 | /// 222 | /// Returns `None` if the type of `self` does not match the type of the 223 | /// index, for example if the index is a string and `self` is an array or a 224 | /// number. Also returns `None` if the given key does not exist in the map 225 | /// or the given index is not within the bounds of the array. 226 | /// 227 | /// ```rust,ignore 228 | /// # #[macro_use] 229 | /// # extern crate sexpr; 230 | /// # 231 | /// # fn main() { 232 | /// let object = sexp!(((A . 65) (B . 66) (C . 67))); 233 | /// assert_eq!(*object.get("A").unwrap(), sexp!(65)); 234 | /// 235 | /// let array = sexp!((A B C)); 236 | /// assert_eq!(*array.get(2).unwrap(), sexp!("C")); 237 | /// 238 | /// assert_eq!(array.get("A"), None); 239 | /// # } 240 | /// ``` 241 | /// 242 | /// Square brackets can also be used to index into a value in a more concise 243 | /// way. This returns `Value::Null` in cases where `get` would have returned 244 | /// `None`. 245 | /// 246 | /// ```rust,ignore 247 | /// # #[macro_use] 248 | /// # extern crate sexpr; 249 | /// # 250 | /// # fn main() { 251 | /// let object = sexp!(( 252 | /// (A . ("a" "á" "à")) 253 | /// (B . ("b" "b́")) 254 | /// (C . ("c" "ć" "ć̣" "ḉ")) 255 | /// )); 256 | /// assert_eq!(object["B"][0], sexp!("b")); 257 | /// 258 | /// assert_eq!(object["D"], sexp!(null)); 259 | /// assert_eq!(object[0]["x"]["y"]["z"], sexp!(null)); 260 | /// # } 261 | /// ``` 262 | pub fn get(&self, _index: I) -> Option<&Sexp> { 263 | unimplemented!() 264 | } 265 | 266 | // fn search_alist(&self, key: S) -> Option 267 | // { 268 | // let key = key.to_string(); 269 | // match *self { 270 | // Sexp::List(ref elts) => { 271 | // for elt in elts { 272 | // match *elt { 273 | // Sexp::Pair(Some(car), cdr) => { 274 | // if (*car).to_string() == key { 275 | // return cdr.and_then(|x| Some(*x)); 276 | // } 277 | // } 278 | // _ => return None 279 | // } 280 | // } 281 | // } 282 | // } 283 | 284 | } 285 | 286 | /// Convert a `T` into `sexpr::Sexp` which is an enum that can represent 287 | /// any valid S-expression data. 288 | /// 289 | /// ```rust,ignore 290 | /// extern crate serde; 291 | /// 292 | /// #[macro_use] 293 | /// extern crate serde_derive; 294 | /// 295 | /// #[macro_use] 296 | /// extern crate sexpr; 297 | /// 298 | /// use std::error::Error; 299 | /// 300 | /// #[derive(Serialize)] 301 | /// struct User { 302 | /// fingerprint: String, 303 | /// location: String, 304 | /// } 305 | /// 306 | /// fn compare_values() -> Result<(), Box> { 307 | /// let u = User { 308 | /// fingerprint: "0xF9BA143B95FF6D82".to_owned(), 309 | /// location: "Menlo Park, CA".to_owned(), 310 | /// }; 311 | /// 312 | /// // The type of `expected` is `sexpr::Sexp` 313 | /// let expected = sexp!(( 314 | /// (fingerprint . "0xF9BA143B95FF6D82") 315 | /// (location . "Menlo Park, CA") 316 | /// )); 317 | /// 318 | /// let v = sexpr::to_value(u).unwrap(); 319 | /// assert_eq!(v, expected); 320 | /// 321 | /// Ok(()) 322 | /// } 323 | /// # 324 | /// # fn main() { 325 | /// # compare_values().unwrap(); 326 | /// # } 327 | /// ``` 328 | /// 329 | /// # Errors 330 | /// 331 | /// This conversion can fail if `T`'s implementation of `Serialize` decides to 332 | /// fail, or if `T` contains a map with non-string keys. 333 | /// 334 | /// ```rust,ignore 335 | /// extern crate sexpr; 336 | /// 337 | /// use std::collections::BTreeMap; 338 | /// 339 | /// fn main() { 340 | /// // The keys in this map are vectors, not strings. 341 | /// let mut map = BTreeMap::new(); 342 | /// map.insert(vec![32, 64], "x86"); 343 | /// 344 | /// println!("{}", sexpr::to_value(map).unwrap_err()); 345 | /// } 346 | /// ``` 347 | #[cfg_attr(feature = "cargo-clippy", allow(needless_pass_by_value))] 348 | // Taking by value is more friendly to iterator adapters, option and result 349 | // consumers, etc. 350 | pub fn to_value(value: T) -> Result 351 | where 352 | T: Serialize, 353 | { 354 | value.serialize(Serializer) 355 | } 356 | 357 | /// Interpret a `sexpr::Sexp` as an instance of type `T`. 358 | /// 359 | /// This conversion can fail if the structure of the Sexp does not match the 360 | /// structure expected by `T`, for example if `T` is a struct type but the Sexp 361 | /// contains something other than a S-expression map. It can also fail if the structure 362 | /// is correct but `T`'s implementation of `Deserialize` decides that something 363 | /// is wrong with the data, for example required struct fields are missing from 364 | /// the S-expression map or some number is too big to fit in the expected primitive 365 | /// type. 366 | /// 367 | /// ```rust,ignore 368 | /// #[macro_use] 369 | /// extern crate sexpr; 370 | /// 371 | /// #[macro_use] 372 | /// extern crate serde_derive; 373 | /// 374 | /// extern crate serde; 375 | /// 376 | /// #[derive(Deserialize, Debug)] 377 | /// struct User { 378 | /// fingerprint: String, 379 | /// location: String, 380 | /// } 381 | /// 382 | /// fn main() { 383 | /// // The type of `s` is `sexpr::Sexp` 384 | /// let s = sexp!(( 385 | /// (fingerprint . "0xF9BA143B95FF6D82") 386 | /// (location . "Menlo Park, CA") 387 | /// )); 388 | /// 389 | /// let u: User = sexpr::from_value(s).unwrap(); 390 | /// println!("{:#?}", u); 391 | /// } 392 | /// ``` 393 | pub fn from_value(value: Sexp) -> Result 394 | where 395 | T: DeserializeOwned, 396 | { 397 | T::deserialize(value) 398 | } 399 | -------------------------------------------------------------------------------- /src/sexp/ser.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | 9 | use serde::{self, Serialize}; 10 | use error::{Error, ErrorCode}; 11 | use number::Number; 12 | use atom::{Atom}; 13 | use sexp::{Sexp, to_value}; 14 | 15 | 16 | impl Serialize for Sexp { 17 | #[inline] 18 | fn serialize(&self, serializer: S) -> Result 19 | where S: ::serde::Serializer, 20 | { 21 | match *self { 22 | Sexp::Nil => serializer.serialize_unit(), 23 | Sexp::Boolean(b) => serializer.serialize_bool(b), 24 | Sexp::Number(ref n) => n.serialize(serializer), 25 | Sexp::Atom(ref atom) => atom.serialize(serializer), 26 | Sexp::List(ref v) => v.serialize(serializer), 27 | Sexp::Pair(_, _) => { 28 | unimplemented!() 29 | }, 30 | // Sexp::Pair(Some(_), None) => unimplemented!(), 31 | // Sexp::Pair(None, Some(_)) => unimplemented!(), 32 | // Sexp::Pair(None, None) => unimplemented!(), 33 | } 34 | } 35 | } 36 | 37 | pub struct Serializer; 38 | 39 | impl serde::Serializer for Serializer { 40 | type Ok = Sexp; 41 | type Error = Error; 42 | 43 | type SerializeSeq = SerializeVec; 44 | type SerializeTuple = SerializeVec; 45 | type SerializeTupleStruct = SerializeVec; 46 | type SerializeTupleVariant = SerializeTupleVariant; 47 | // XXX TODO 48 | type SerializeMap = SerializeMap; 49 | type SerializeStruct = SerializeMap; 50 | type SerializeStructVariant = SerializeStructVariant; 51 | 52 | #[inline] 53 | fn serialize_bool(self, value: bool) -> Result { 54 | Ok(Sexp::Boolean(value)) 55 | } 56 | 57 | #[inline] 58 | fn serialize_i8(self, value: i8) -> Result { 59 | self.serialize_i64(value as i64) 60 | } 61 | 62 | #[inline] 63 | fn serialize_i16(self, value: i16) -> Result { 64 | self.serialize_i64(value as i64) 65 | } 66 | 67 | #[inline] 68 | fn serialize_i32(self, value: i32) -> Result { 69 | self.serialize_i64(value as i64) 70 | } 71 | 72 | fn serialize_i64(self, value: i64) -> Result { 73 | Ok(Sexp::Number(value.into())) 74 | } 75 | 76 | #[inline] 77 | fn serialize_u8(self, value: u8) -> Result { 78 | self.serialize_u64(value as u64) 79 | } 80 | 81 | #[inline] 82 | fn serialize_u16(self, value: u16) -> Result { 83 | self.serialize_u64(value as u64) 84 | } 85 | 86 | #[inline] 87 | fn serialize_u32(self, value: u32) -> Result { 88 | self.serialize_u64(value as u64) 89 | } 90 | 91 | #[inline] 92 | fn serialize_u64(self, value: u64) -> Result { 93 | Ok(Sexp::Number(value.into())) 94 | } 95 | 96 | #[inline] 97 | fn serialize_f32(self, value: f32) -> Result { 98 | self.serialize_f64(value as f64) 99 | } 100 | 101 | #[inline] 102 | fn serialize_f64(self, value: f64) -> Result { 103 | Ok(Number::from_f64(value).map_or(Sexp::Nil, Sexp::Number)) 104 | } 105 | 106 | #[inline] 107 | fn serialize_char(self, value: char) -> Result { 108 | let mut s = String::new(); 109 | s.push(value); 110 | self.serialize_str(&s) 111 | } 112 | 113 | #[inline] 114 | fn serialize_str(self, value: &str) -> Result { 115 | Ok(Sexp::Atom(value.to_owned().into())) 116 | } 117 | 118 | fn serialize_bytes(self, value: &[u8]) -> Result { 119 | let vec = value.iter().map(|&b| Sexp::Number(b.into())).collect(); 120 | Ok(Sexp::List(vec)) 121 | } 122 | 123 | #[inline] 124 | fn serialize_unit(self) -> Result { 125 | Ok(Sexp::Nil) 126 | } 127 | 128 | #[inline] 129 | fn serialize_unit_struct(self, _name: &'static str) -> Result { 130 | self.serialize_unit() 131 | } 132 | 133 | #[inline] 134 | fn serialize_unit_variant( 135 | self, 136 | _name: &'static str, 137 | _variant_index: u32, 138 | variant: &'static str, 139 | ) -> Result { 140 | self.serialize_str(variant) 141 | } 142 | 143 | #[inline] 144 | fn serialize_newtype_struct( 145 | self, 146 | _name: &'static str, 147 | value: &T, 148 | ) -> Result 149 | where 150 | T: Serialize, 151 | { 152 | value.serialize(self) 153 | } 154 | 155 | fn serialize_newtype_variant( 156 | self, 157 | _name: &'static str, 158 | _variant_index: u32, 159 | _variant: &'static str, 160 | _value: &T, 161 | ) -> Result 162 | where 163 | T: Serialize, 164 | { 165 | unimplemented!() 166 | } 167 | 168 | #[inline] 169 | fn serialize_none(self) -> Result { 170 | self.serialize_unit() 171 | } 172 | 173 | #[inline] 174 | fn serialize_some(self, value: &T) -> Result 175 | where 176 | T: Serialize, 177 | { 178 | value.serialize(self) 179 | } 180 | 181 | fn serialize_seq(self, len: Option) -> Result { 182 | Ok(SerializeVec { vec: Vec::with_capacity(len.unwrap_or(0)) }) 183 | } 184 | 185 | fn serialize_tuple(self, len: usize) -> Result { 186 | self.serialize_seq(Some(len)) 187 | } 188 | 189 | fn serialize_tuple_struct( 190 | self, 191 | _name: &'static str, 192 | len: usize, 193 | ) -> Result { 194 | self.serialize_seq(Some(len)) 195 | } 196 | 197 | fn serialize_tuple_variant( 198 | self, 199 | _name: &'static str, 200 | _variant_index: u32, 201 | variant: &'static str, 202 | len: usize, 203 | ) -> Result { 204 | Ok( 205 | SerializeTupleVariant { 206 | name: String::from(variant), 207 | vec: Vec::with_capacity(len), 208 | }, 209 | ) 210 | } 211 | 212 | fn serialize_map(self, _len: Option) -> Result { 213 | unimplemented!() 214 | } 215 | 216 | fn serialize_struct( 217 | self, 218 | _name: &'static str, 219 | len: usize, 220 | ) -> Result { 221 | self.serialize_map(Some(len)) 222 | } 223 | 224 | fn serialize_struct_variant( 225 | self, 226 | _name: &'static str, 227 | _variant_index: u32, 228 | _variant: &'static str, 229 | _len: usize, 230 | ) -> Result { 231 | unimplemented!() 232 | } 233 | } 234 | 235 | #[doc(hidden)] 236 | pub struct SerializeVec { 237 | vec: Vec, 238 | } 239 | 240 | #[doc(hidden)]#[allow(dead_code)] 241 | pub struct SerializeTupleVariant { 242 | name: String, 243 | vec: Vec, 244 | } 245 | 246 | impl serde::ser::SerializeSeq for SerializeVec { 247 | type Ok = Sexp; 248 | type Error = Error; 249 | 250 | fn serialize_element(&mut self, value: &T) -> Result<(), Error> 251 | where 252 | T: Serialize, 253 | { 254 | self.vec.push(try!(to_value(&value))); 255 | Ok(()) 256 | } 257 | 258 | fn end(self) -> Result { 259 | Ok(Sexp::List(self.vec)) 260 | } 261 | } 262 | 263 | impl serde::ser::SerializeTuple for SerializeVec { 264 | type Ok = Sexp; 265 | type Error = Error; 266 | 267 | fn serialize_element(&mut self, value: &T) -> Result<(), Error> 268 | where 269 | T: Serialize, 270 | { 271 | serde::ser::SerializeSeq::serialize_element(self, value) 272 | } 273 | 274 | fn end(self) -> Result { 275 | serde::ser::SerializeSeq::end(self) 276 | } 277 | } 278 | 279 | impl serde::ser::SerializeTupleStruct for SerializeVec { 280 | type Ok = Sexp; 281 | type Error = Error; 282 | 283 | fn serialize_field(&mut self, value: &T) -> Result<(), Error> 284 | where 285 | T: Serialize, 286 | { 287 | serde::ser::SerializeSeq::serialize_element(self, value) 288 | } 289 | 290 | fn end(self) -> Result { 291 | serde::ser::SerializeSeq::end(self) 292 | } 293 | } 294 | 295 | impl serde::ser::SerializeTupleVariant for SerializeTupleVariant { 296 | type Ok = Sexp; 297 | type Error = Error; 298 | 299 | fn serialize_field(&mut self, value: &T) -> Result<(), Error> 300 | where 301 | T: Serialize, 302 | { 303 | self.vec.push(try!(to_value(&value))); 304 | Ok(()) 305 | } 306 | 307 | fn end(self) -> Result { 308 | unimplemented!() 309 | } 310 | } 311 | 312 | #[doc(hidden)] 313 | pub struct SerializeMap { 314 | next_key: Option, 315 | } 316 | 317 | impl serde::ser::SerializeMap for SerializeMap { 318 | type Ok = Sexp; 319 | type Error = Error; 320 | 321 | fn serialize_key(&mut self, key: &T) -> Result<(), Error> 322 | where 323 | T: Serialize, 324 | { 325 | match try!(to_value(&key)) { 326 | Sexp::Atom(a) => self.next_key = Some(a.as_string()), 327 | Sexp::Number(n) => { 328 | if n.is_u64() || n.is_i64() { 329 | self.next_key = Some(n.to_string()) 330 | } else { 331 | return Err(Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)); 332 | } 333 | } 334 | _ => return Err(Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)), 335 | }; 336 | Ok(()) 337 | } 338 | 339 | fn serialize_value(&mut self, _value: &T) -> Result<(), Error> 340 | where 341 | T: Serialize, 342 | { 343 | unimplemented!() 344 | } 345 | 346 | fn end(self) -> Result { 347 | unimplemented!() 348 | } 349 | } 350 | 351 | impl serde::ser::SerializeStruct for SerializeMap { 352 | type Ok = Sexp; 353 | type Error = Error; 354 | 355 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> 356 | where 357 | T: Serialize, 358 | { 359 | try!(serde::ser::SerializeMap::serialize_key(self, key)); 360 | serde::ser::SerializeMap::serialize_value(self, value) 361 | } 362 | 363 | fn end(self) -> Result { 364 | serde::ser::SerializeMap::end(self) 365 | } 366 | } 367 | 368 | #[doc(hidden)] 369 | pub struct SerializeStructVariant { 370 | name: String, 371 | values: Vec, 372 | } 373 | 374 | impl serde::ser::SerializeStructVariant for SerializeStructVariant { 375 | type Ok = Sexp; 376 | type Error = Error; 377 | 378 | fn serialize_field(&mut self, key: &'static str, value: &T) -> Result<(), Error> 379 | where 380 | T: Serialize, 381 | { 382 | self.values.push( 383 | Sexp::new_entry(key, to_value(&value).ok().unwrap_or(Sexp::Nil)) 384 | ); 385 | Ok(()) 386 | } 387 | 388 | fn end(self) -> Result { 389 | Ok(Sexp::new_entry(self.name, Sexp::List(self.values))) 390 | } 391 | } 392 | -------------------------------------------------------------------------------- /tests/test.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Zephyr Pellerin 2 | // 3 | // Licensed under the Apache License, Version 2.0 or the MIT license 5 | // , at your 6 | // option. This file may not be copied, modified, or distributed 7 | // except according to those terms. 8 | #![allow(unused_imports)] 9 | #[macro_use] 10 | extern crate serde_derive; 11 | 12 | extern crate serde; 13 | extern crate serde_bytes; 14 | extern crate sexpr; 15 | 16 | use std::fmt::{Debug}; 17 | use std::{f32, f64}; 18 | use std::{u32, u64}; 19 | use std::{i8, i16, i32, i64}; 20 | 21 | //use serde::de::{self, Deserialize}; 22 | use serde::ser::{self}; 23 | 24 | use sexpr::{to_string, to_value}; 25 | 26 | 27 | #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 28 | #[serde(deny_unknown_fields)] 29 | enum Animal { 30 | Dog, 31 | Frog(String, Vec), 32 | Cat { age: usize, name: String }, 33 | AntHive(Vec), 34 | } 35 | 36 | #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 37 | struct Inner { 38 | a: (), 39 | b: usize, 40 | c: Vec, 41 | } 42 | 43 | #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 44 | struct Outer { 45 | inner: Vec, 46 | } 47 | 48 | fn test_encode_ok(errors: &[(T, &str)]) 49 | where 50 | T: PartialEq + Debug + ser::Serialize, 51 | { 52 | for &(ref value, out) in errors { 53 | let out = out.to_string(); 54 | 55 | let s = to_string(value).unwrap(); 56 | assert_eq!(s, out); 57 | 58 | // deserializer logic 59 | // disabled for now (you can tell bcuz there are comments) 60 | // let v = to_value(&value).unwrap(); 61 | // let s = to_string(&v).unwrap(); 62 | // assert_eq!(s, out); 63 | } 64 | } 65 | 66 | #[test] 67 | fn test_write_u64() { 68 | let tests = &[(3u64, "3"), (u64::MAX, &u64::MAX.to_string())]; 69 | test_encode_ok(tests); 70 | } 71 | 72 | #[test] 73 | fn test_write_i64() { 74 | let tests = &[ 75 | (3i64, "3"), 76 | (-2i64, "-2"), 77 | (-1234i64, "-1234"), 78 | (i64::MIN, &i64::MIN.to_string()), 79 | ]; 80 | test_encode_ok(tests); 81 | } 82 | 83 | #[test] 84 | fn test_write_f64() { 85 | let tests = &[ 86 | (3.0, "3.0"), 87 | (3.1, "3.1"), 88 | (-1.5, "-1.5"), 89 | (0.5, "0.5"), 90 | ]; 91 | test_encode_ok(tests); 92 | } 93 | 94 | 95 | #[test] 96 | fn test_write_str() { 97 | let tests = &[("", "\"\""), ("foo", "\"foo\"")]; 98 | test_encode_ok(tests); 99 | } 100 | 101 | #[test] 102 | fn test_write_bool() { 103 | let tests = &[(true, "#t"), (false, "#f")]; 104 | test_encode_ok(tests); 105 | } 106 | 107 | #[test] 108 | fn test_write_sym() { 109 | let tests = &[("a", "\"a\"")]; 110 | test_encode_ok(tests); 111 | } 112 | 113 | 114 | // /// 115 | // /// ```rust 116 | // /// # #[macro_use] 117 | // /// # extern crate sexpr; 118 | // /// # 119 | // /// # use sexpr::atom::Atom; 120 | // /// # fn main() { 121 | // /// assert!(Atom::Keyword("keyword"), Atom::discriminate("#:keyword")); 122 | // /// assert!(Atom::Symbol("symbol"), Atom::discriminate("symbol")); 123 | // /// assert!(Atom::String("string"), Atom::discriminate(r#""string""#)); 124 | // /// # } 125 | // /// ``` 126 | --------------------------------------------------------------------------------