├── .github └── workflows │ └── rust.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE ├── README.md ├── benches ├── bench.rs ├── gh.json ├── hdfs.json ├── hdfs_with_array.json ├── simple-parse-bench.json └── wiki.json ├── rustfmt.toml └── src ├── cowstr.rs ├── de.rs ├── deserializer.rs ├── index.rs ├── lib.rs ├── num.rs ├── object_vec.rs ├── owned.rs ├── ser.rs └── value.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | test: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | - name: Build 20 | run: cargo build --verbose 21 | - name: Run tests cowkeys ff 22 | run: cargo test --verbose --features cowkeys 23 | - name: Run tests no default 24 | run: cargo test --verbose --no-default-features 25 | - name: Run tests default 26 | run: cargo test --verbose 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.7.1 (2024-11-02) 2 | ================== 3 | strip extra iteration when initialising ObjectAsVec https://github.com/PSeitz/serde_json_borrow/pull/29 (Thanks @meskill) 4 | 5 | 0.7.0 (2024-10-28) 6 | ================== 7 | impl `Deserializer` for `Value`. This enables deserialization into other types. 8 | 9 | 0.6.0 (2024-08-28) 10 | ================== 11 | improve returned lifetimes https://github.com/PSeitz/serde_json_borrow/pull/19 (Thanks @meskill) 12 | 13 | 0.5.0 (2024-05-24) 14 | ================== 15 | add `cowkeys` featureflag 16 | `cowkeys` uses `Cow` instead of `&str` as keys in objects. This enables support for escaped data in keys. 17 | 18 | 0.4.7 (2024-05-23) 19 | ================== 20 | add `From` methods for type like u64 to easily convert into `Value<'a>` 21 | 22 | 0.4.6 (2024-05-23) 23 | ================== 24 | add `Clone, Debug, Eq, PartialEq, Hash` to OwnedValue 25 | add `Hash` to Value 26 | implement numeric visitor, visit_u8, i8 etc. 27 | 28 | 0.4.5 (2024-05-22) 29 | ================== 30 | add `get_mut`, `insert` to serde_json_borrow::Map 31 | add `insert_or_get_mut` to serde_json_borrow::Map as `entry()` alternative 32 | add From<&Value> for `serde_json::Value` 33 | add From for serde_json::Map 34 | 35 | 0.4.4 (2024-05-22) 36 | ================== 37 | Export `ObjectAsVec` as `serde_json_borrow::Map` to easy migration from `serde_json::Map` 38 | Impl `Default` for `serde_json_borrow::Map` 39 | 40 | 0.4.3 (2024-05-22) 41 | ================== 42 | add `From for `ObjectAsVec` 43 | 44 | 0.4.2 (2024-05-20) 45 | ================== 46 | * Add `OwnedValue::from_slice`, `OwnedValue::from_str` and `OneValue::from_string` 47 | * Add `Deref` for `OwnedValue` https://github.com/PSeitz/serde_json_borrow/pull/16 48 | 49 | 0.4.1 (2024-05-20) 50 | ================== 51 | * Implement `Display` on serde_json_borrow::Value https://github.com/PSeitz/serde_json_borrow/pull/15 52 | 53 | 0.4 (2024-05-20) 54 | ================== 55 | * Add Object access methods on Objects via `ObjectAsVec` wrapper https://github.com/PSeitz/serde_json_borrow/pull/12 56 | 57 | json objects are backed by `Vec` in `serde_json_borrow`, but it was missing the same methods like `BtreeMap`, e.g. `.get` `get_key_value`. 58 | ObjectAsVec provides these methods. 59 | 60 | 0.3 (2023-09-19) 61 | ================== 62 | * Add as_object, as_array methods https://github.com/PSeitz/serde_json_borrow/pull/8 63 | 64 | 0.2 (2023-07-07) 65 | ================== 66 | * Add serialization https://github.com/PSeitz/serde_json_borrow/pull/6 (Thanks @dtolnay) 67 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json_borrow" 3 | categories = ["parsing", "parser-implementations", "encoding"] 4 | authors = ["Pascal Seitz "] 5 | description = "Provides JSON deserialization into a borrowed DOM" 6 | version = "0.7.1" 7 | edition = "2021" 8 | license = "MIT" 9 | keywords = ["JSON", "serde", "deserialization", "ref", "borrowed"] 10 | exclude = ["benches/**/*.json"] 11 | readme = "README.md" 12 | repository = "https://github.com/PSeitz/serde_json_borrow" 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | serde = { version = "1.0.145", features = ["derive"] } 18 | serde_json = "1.0.86" 19 | 20 | [dev-dependencies] 21 | binggan = "0.14.0" 22 | simd-json = "0.13.10" 23 | 24 | [features] 25 | default = ["cowkeys"] 26 | # Uses Cow instead of &str. This enables support for escaped data in keys. 27 | # But it costs some deserialization performance. 28 | cowkeys = [] 29 | 30 | 31 | [[bench]] 32 | name = "bench" 33 | harness = false 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Crates.io](https://img.shields.io/crates/v/serde_json_borrow.svg)](https://crates.io/crates/serde_json_borrow) 2 | [![Docs](https://docs.rs/serde_json_borrow/badge.svg)](https://docs.rs/crate/serde_json_borrow/) 3 | 4 | # Serde JSON Borrow 5 | 6 | Up to 2x faster JSON parsing for NDJSON (Newline Delimited JSON format) type use cases. 7 | 8 | `serde_json_borrow` deserializes JSON from `&'ctx str` into `serde_json_borrow::Value<'ctx>` DOM, by trying to reference the original bytes, instead of copying them into `Strings`. 9 | 10 | In contrast the default [serde_json](https://github.com/serde-rs/json) parses into an owned `serde_json::Value`. Every `String` encountered is getting copied and 11 | therefore allocated. That's great for ergonomonics, but not great for performance. 12 | Especially in cases where the DOM representation is just an intermediate struct. 13 | 14 | To get a little bit more performance, `serde_json_borrow` pushes the (key,values) for JSON objects into a `Vec` instead of using a `BTreeMap`. Access works via 15 | an iterator, which has the same API when iterating the `BTreeMap`. 16 | 17 | ## OwnedValue 18 | You can take advantage of `OwnedValue` to parse a `String` containing unparsed `JSON` into a `Value` without having to worry about lifetimes, 19 | as `OwnedValue` will take ownership of the `String` and reference slices of it, rather than making copies. 20 | 21 | Note: `OwnedValue` does not implement `Deserialize`. 22 | 23 | # Limitations 24 | The feature flag `cowkeys` uses `Cow` instead of `&str` as keys in objects. This enables support for escaped data in keys. 25 | Without the `cowkeys` feature flag `&str` is used, which does not allow any JSON escaping characters in keys. 26 | 27 | List of _unsupported_ characters (https://www.json.org/json-en.html) in keys without `cowkeys` feature flag. 28 | 29 | ``` 30 | \" represents the quotation mark character (U+0022). 31 | \\ represents the reverse solidus character (U+005C). 32 | \/ represents the solidus character (U+002F). 33 | \b represents the backspace character (U+0008). 34 | \f represents the form feed character (U+000C). 35 | \n represents the line feed character (U+000A). 36 | \r represents the carriage return character (U+000D). 37 | \t represents the character tabulation character (U+0009). 38 | ``` 39 | 40 | # Benchmark 41 | 42 | `cargo bench` 43 | 44 | * simple_json -> flat object with some keys 45 | * hdfs -> log 46 | * wiki -> few keys with large text body 47 | * gh-archive -> highly nested object 48 | ``` 49 | simple_json 50 | serde_json Avg: 139.29 MiB/s Median: 139.53 MiB/s [134.51 MiB/s .. 140.45 MiB/s] 51 | serde_json_borrow Avg: 210.33 MiB/s Median: 209.66 MiB/s [204.08 MiB/s .. 214.28 MiB/s] 52 | SIMD_json_borrow Avg: 140.36 MiB/s Median: 140.44 MiB/s [138.96 MiB/s .. 141.75 MiB/s] 53 | hdfs 54 | serde_json Avg: 284.64 MiB/s Median: 284.60 MiB/s [280.98 MiB/s .. 286.46 MiB/s] 55 | serde_json_borrow Avg: 372.99 MiB/s Median: 371.75 MiB/s [365.97 MiB/s .. 379.96 MiB/s] 56 | SIMD_json_borrow Avg: 294.41 MiB/s Median: 294.96 MiB/s [287.76 MiB/s .. 296.96 MiB/s] 57 | hdfs_with_array 58 | serde_json Avg: 194.50 MiB/s Median: 200.41 MiB/s [155.44 MiB/s .. 211.49 MiB/s] 59 | serde_json_borrow Avg: 275.01 MiB/s Median: 282.74 MiB/s [208.35 MiB/s .. 289.78 MiB/s] 60 | SIMD_json_borrow Avg: 206.34 MiB/s Median: 210.52 MiB/s [180.99 MiB/s .. 220.30 MiB/s] 61 | wiki 62 | serde_json Avg: 439.95 MiB/s Median: 441.28 MiB/s [429.97 MiB/s .. 444.82 MiB/s] 63 | serde_json_borrow Avg: 484.74 MiB/s Median: 485.29 MiB/s [471.38 MiB/s .. 489.16 MiB/s] 64 | SIMD_json_borrow Avg: 576.57 MiB/s Median: 578.11 MiB/s [554.03 MiB/s .. 586.18 MiB/s] 65 | gh-archive 66 | serde_json Avg: 176.21 MiB/s Median: 176.37 MiB/s [172.52 MiB/s .. 177.78 MiB/s] 67 | serde_json_borrow Avg: 363.58 MiB/s Median: 364.02 MiB/s [355.28 MiB/s .. 374.10 MiB/s] 68 | SIMD_json_borrow Avg: 383.66 MiB/s Median: 386.94 MiB/s [363.80 MiB/s .. 400.25 MiB/s] 69 | 70 | ``` 71 | 72 | # TODO 73 | Instead of parsing a JSON object into a `Vec`, a `BTreeMap` could be enabled via a feature flag. 74 | 75 | # Mutability 76 | `OwnedValue` is immutable by design. 77 | If you need to mutate the `Value` you can convert it to `serde_json::Value`. 78 | 79 | Here is an example why mutability won't work: 80 | 81 | https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bb0b919acc8930e71bdefdfc6a6d5240 82 | ```rust 83 | use std::io; 84 | 85 | use std::borrow::Cow; 86 | 87 | 88 | /// Parses a `String` into `Value`, by taking ownership of `String` and reference slices from it in 89 | /// contrast to copying the contents. 90 | /// 91 | /// This is done to mitigate lifetime issues. 92 | pub struct OwnedValue { 93 | /// Keep owned data, to be able to safely reference it from Value<'static> 94 | _data: String, 95 | value: Vec>, 96 | } 97 | 98 | impl OwnedValue { 99 | /// Takes ownership of a `String` and parses it into a DOM. 100 | pub fn parse_from(data: String) -> io::Result { 101 | let value = vec![Cow::from(data.as_str())]; 102 | let value = unsafe { extend_lifetime(value) }; 103 | Ok(Self { _data: data, value }) 104 | } 105 | 106 | /// Returns the `Value` reference. 107 | pub fn get_value<'a>(&'a self) -> &'a Vec> { 108 | &self.value 109 | } 110 | /// This cast will break the borrow checker 111 | pub fn get_value_mut<'a>(&'a mut self) -> &'a mut Vec> { 112 | unsafe{std::mem::transmute::<&mut Vec>, &mut Vec>>(&mut self.value)} 113 | } 114 | } 115 | 116 | unsafe fn extend_lifetime<'b>(r: Vec>) -> Vec> { 117 | std::mem::transmute::>, Vec>>(r) 118 | } 119 | 120 | fn main() { 121 | let mut v1 = OwnedValue::parse_from(String::from("oop")).unwrap(); 122 | let mut v2 = OwnedValue::parse_from(String::from("oop")).unwrap(); 123 | let oop = v1.get_value().last().unwrap().clone(); 124 | v2.get_value_mut().push(oop); 125 | drop(v1); 126 | let oop = v2.get_value_mut().pop().unwrap(); 127 | println!("oop: '{oop}'"); 128 | } 129 | ``` 130 | -------------------------------------------------------------------------------- /benches/bench.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::hint::black_box; 3 | use std::io::{BufRead, BufReader}; 4 | 5 | use binggan::plugins::{BPUTrasher, CacheTrasher}; 6 | use binggan::{BenchRunner, PeakMemAlloc, INSTRUMENTED_SYSTEM}; 7 | use serde_json_borrow::OwnedValue; 8 | 9 | #[global_allocator] 10 | pub static GLOBAL: &PeakMemAlloc = &INSTRUMENTED_SYSTEM; 11 | 12 | fn lines_for_file(file: &str) -> impl Iterator { 13 | BufReader::new(File::open(file).unwrap()) 14 | .lines() 15 | .map(|line| line.unwrap()) 16 | } 17 | 18 | fn main() { 19 | access_bench(); 20 | parse_bench(); 21 | } 22 | 23 | fn parse_bench() { 24 | let mut named_data = Vec::new(); 25 | 26 | let mut add = |name, path| { 27 | named_data.push(( 28 | name, 29 | ( 30 | move || lines_for_file(path), 31 | File::open(path).unwrap().metadata().unwrap().len(), 32 | ), 33 | )); 34 | }; 35 | 36 | add("simple_json", "./benches/simple-parse-bench.json"); 37 | add("hdfs", "./benches/hdfs.json"); 38 | add("hdfs_with_array", "./benches/hdfs_with_array.json"); 39 | add("wiki", "./benches/wiki.json"); 40 | add("gh-archive", "./benches/gh.json"); 41 | 42 | let mut runner: BenchRunner = BenchRunner::new(); 43 | runner 44 | .add_plugin(CacheTrasher::default()) 45 | .add_plugin(BPUTrasher::default()); 46 | runner.set_name("parse"); 47 | 48 | for (name, (input_gen, size)) in named_data { 49 | let mut runner = runner.new_group(); 50 | runner.set_input_size(size as usize); 51 | runner.set_name(name); 52 | 53 | let access = get_access_for_input_name(name); 54 | runner.register("serde_json", move |_data| { 55 | let mut val = None; 56 | for line in input_gen() { 57 | let json: serde_json::Value = serde_json::from_str(&line).unwrap(); 58 | val = Some(json); 59 | } 60 | black_box(val); 61 | }); 62 | 63 | runner.register("serde_json + access by key", move |_data| { 64 | let mut total_size = 0; 65 | for line in input_gen() { 66 | let json: serde_json::Value = serde_json::from_str(&line).unwrap(); 67 | total_size += access_json(&json, access); 68 | } 69 | black_box(total_size); 70 | }); 71 | runner.register("serde_json_borrow", move |_data| { 72 | let mut val = None; 73 | for line in input_gen() { 74 | let json: OwnedValue = OwnedValue::parse_from(line).unwrap(); 75 | val = Some(json); 76 | } 77 | black_box(val); 78 | }); 79 | 80 | runner.register("serde_json_borrow + access by key", move |_data| { 81 | let mut total_size = 0; 82 | for line in input_gen() { 83 | let json: OwnedValue = OwnedValue::parse_from(line).unwrap(); 84 | total_size += access_json_borrowed(&json, access); 85 | } 86 | black_box(total_size); 87 | }); 88 | 89 | runner.register("SIMD_json_borrow", move |_data| { 90 | for line in input_gen() { 91 | let mut data: Vec = line.into(); 92 | let v: simd_json::BorrowedValue = simd_json::to_borrowed_value(&mut data).unwrap(); 93 | black_box(v); 94 | } 95 | }); 96 | runner.run(); 97 | } 98 | } 99 | 100 | fn get_access_for_input_name(name: &str) -> &[&[&'static str]] { 101 | match name { 102 | "hdfs" => &[&["severity_text", "timestamp", "body"]], 103 | "simple_json" => &[&["last_name"]], 104 | "gh-archive" => &[ 105 | &["id"], 106 | &["type"], 107 | &["actor", "avatar_url"], 108 | &["actor", "url"], 109 | &["actor", "id"], 110 | &["actor", "login"], 111 | &["actor", "url"], 112 | &["actor", "avatar_url"], 113 | &["type"], 114 | &["actor", "id"], 115 | &["publuc"], 116 | &["created_at"], 117 | ], 118 | "wiki" => &[&["body", "url"]], 119 | _ => &[], 120 | } 121 | } 122 | 123 | fn access_bench() { 124 | let mut runner: BenchRunner = BenchRunner::new(); 125 | runner 126 | .add_plugin(CacheTrasher::default()) 127 | .add_plugin(BPUTrasher::default()); 128 | runner.set_name("access"); 129 | 130 | let file_name_path_and_access = vec![ 131 | ("simple_json", "./benches/simple-parse-bench.json"), 132 | ("gh-archive", "./benches/gh.json"), 133 | ]; 134 | 135 | for (name, path) in &file_name_path_and_access { 136 | let access = get_access_for_input_name(name); 137 | let file_size = File::open(path).unwrap().metadata().unwrap().len(); 138 | let serde_jsons: Vec = lines_for_file(path) 139 | .map(|line| serde_json::from_str(&line).unwrap()) 140 | .collect(); 141 | let serde_json_borrows: Vec = lines_for_file(path) 142 | .map(|line| OwnedValue::parse_from(line).unwrap()) 143 | .collect(); 144 | 145 | let mut group = runner.new_group(); 146 | group.set_name(name); 147 | group.set_input_size(file_size as usize); 148 | group.register_with_input("serde_json access", &serde_jsons, move |data| { 149 | let mut total_size = 0; 150 | for el in data.iter() { 151 | // walk the access keys until the end. return 0 if value does not exist 152 | total_size += access_json(el, access); 153 | } 154 | total_size 155 | }); 156 | group.register_with_input( 157 | "serde_json_borrow access", 158 | &serde_json_borrows, 159 | move |data| { 160 | let mut total_size = 0; 161 | for el in data.iter() { 162 | total_size += access_json_borrowed(el, access); 163 | } 164 | total_size 165 | }, 166 | ); 167 | group.run(); 168 | } 169 | } 170 | 171 | fn access_json(el: &serde_json::Value, access: &[&[&str]]) -> usize { 172 | let mut total_size = 0; 173 | // walk the access keys until the end. return 0 if value does not exist 174 | for access in access { 175 | let mut val = Some(el); 176 | for key in *access { 177 | val = val.and_then(|v| v.get(key)); 178 | } 179 | if let Some(v) = val { 180 | total_size += v.as_str().map(|s| s.len()).unwrap_or(0); 181 | } 182 | } 183 | total_size 184 | } 185 | 186 | fn access_json_borrowed(el: &OwnedValue, access: &[&[&str]]) -> usize { 187 | let mut total_size = 0; 188 | for access in access { 189 | // walk the access keys until the end. return 0 if value does not exist 190 | let mut val = el.get_value(); 191 | for key in *access { 192 | val = val.get(*key); 193 | } 194 | if let Some(v) = val.as_str() { 195 | total_size += v.len(); 196 | } 197 | } 198 | total_size 199 | } 200 | -------------------------------------------------------------------------------- /benches/simple-parse-bench.json: -------------------------------------------------------------------------------- 1 | {"id":1,"first_name":"Giulia","last_name":"Chaplain","email":"gchaplain0@ameblo.jp"} 2 | {"id":2,"first_name":"Vivyan","last_name":"Shitliffe","email":"vshitliffe1@skype.com"} 3 | {"id":3,"first_name":"Phip","last_name":"Ribey","email":"pribey2@sitemeter.com"} 4 | {"id":4,"first_name":"Theressa","last_name":"Gamlin","email":"tgamlin3@alibaba.com"} 5 | {"id":5,"first_name":"Monica","last_name":"Buney","email":"mbuney4@abc.net.au"} 6 | {"id":6,"first_name":"Adore","last_name":"Brickhill","email":"abrickhill5@liveinternet.ru"} 7 | {"id":7,"first_name":"Germana","last_name":"Culligan","email":"gculligan6@forbes.com"} 8 | {"id":8,"first_name":"Jorgan","last_name":"Provost","email":"jprovost7@naver.com"} 9 | {"id":9,"first_name":"Dianemarie","last_name":"Dorney","email":"ddorney8@alexa.com"} 10 | {"id":10,"first_name":"Philipa","last_name":"Cocozza","email":"pcocozza9@eventbrite.com"} 11 | {"id":11,"first_name":"Adena","last_name":"Frickey","email":"africkeya@php.net"} 12 | {"id":12,"first_name":"Noelyn","last_name":"Jocelyn","email":"njocelynb@addtoany.com"} 13 | {"id":13,"first_name":"Cammy","last_name":"Norwell","email":"cnorwellc@yale.edu"} 14 | {"id":14,"first_name":"Eadie","last_name":"Pipworth","email":"epipworthd@barnesandnoble.com"} 15 | {"id":15,"first_name":"Tandy","last_name":"Lenahan","email":"tlenahane@tripod.com"} 16 | {"id":16,"first_name":"Honoria","last_name":"Van Weedenburg","email":"hvanweedenburgf@discovery.com"} 17 | {"id":17,"first_name":"Felita","last_name":"O' Mullane","email":"fomullaneg@msu.edu"} 18 | {"id":18,"first_name":"Austin","last_name":"Brownstein","email":"abrownsteinh@prlog.org"} 19 | {"id":19,"first_name":"Leigh","last_name":"Berzins","email":"lberzinsi@walmart.com"} 20 | {"id":20,"first_name":"Rachele","last_name":"Adamsson","email":"radamssonj@csmonitor.com"} 21 | {"id":21,"first_name":"Barbabra","last_name":"Wilacot","email":"bwilacotk@kickstarter.com"} 22 | {"id":22,"first_name":"Griffin","last_name":"Jone","email":"gjonel@google.pl"} 23 | {"id":23,"first_name":"Michel","last_name":"Bothie","email":"mbothiem@shareasale.com"} 24 | {"id":24,"first_name":"Callie","last_name":"Selley","email":"cselleyn@gmpg.org"} 25 | {"id":25,"first_name":"Gleda","last_name":"O'Lahy","email":"golahyo@nih.gov"} 26 | {"id":26,"first_name":"Alia","last_name":"Ladel","email":"aladelp@phpbb.com"} 27 | {"id":27,"first_name":"Gusti","last_name":"McVitty","email":"gmcvittyq@redcross.org"} 28 | {"id":28,"first_name":"Carolann","last_name":"Pachmann","email":"cpachmannr@goodreads.com"} 29 | {"id":29,"first_name":"Agata","last_name":"Nyssen","email":"anyssens@utexas.edu"} 30 | {"id":30,"first_name":"Jerrie","last_name":"Craddy","email":"jcraddyt@cbc.ca"} 31 | {"id":31,"first_name":"Nariko","last_name":"Von Brook","email":"nvonbrooku@comcast.net"} 32 | {"id":32,"first_name":"Zacharias","last_name":"Gobel","email":"zgobelv@wordpress.org"} 33 | {"id":33,"first_name":"Sidnee","last_name":"Whettleton","email":"swhettletonw@lycos.com"} 34 | {"id":34,"first_name":"Orlan","last_name":"Adamovitch","email":"oadamovitchx@hibu.com"} 35 | {"id":35,"first_name":"Lotty","last_name":"Eddolls","email":"leddollsy@oracle.com"} 36 | {"id":36,"first_name":"Sarge","last_name":"Tongue","email":"stonguez@shutterfly.com"} 37 | {"id":37,"first_name":"Dalia","last_name":"Fisbey","email":"dfisbey10@ca.gov"} 38 | {"id":38,"first_name":"Christin","last_name":"Yokel","email":"cyokel11@weebly.com"} 39 | {"id":39,"first_name":"Maryjo","last_name":"Thridgould","email":"mthridgould12@apple.com"} 40 | {"id":40,"first_name":"Maxie","last_name":"Nock","email":"mnock13@symantec.com"} 41 | {"id":41,"first_name":"Shani","last_name":"Breeds","email":"sbreeds14@who.int"} 42 | {"id":42,"first_name":"Loraine","last_name":"Sainthill","email":"lsainthill15@icq.com"} 43 | {"id":43,"first_name":"Lorain","last_name":"Davidou","email":"ldavidou16@hexun.com"} 44 | {"id":44,"first_name":"Ameline","last_name":"Dymoke","email":"adymoke17@usgs.gov"} 45 | {"id":45,"first_name":"Tod","last_name":"Mendenhall","email":"tmendenhall18@skype.com"} 46 | {"id":46,"first_name":"Cloris","last_name":"Pengilley","email":"cpengilley19@upenn.edu"} 47 | {"id":47,"first_name":"Kathi","last_name":"Ortells","email":"kortells1a@state.tx.us"} 48 | {"id":48,"first_name":"Sal","last_name":"Praill","email":"spraill1b@deviantart.com"} 49 | {"id":49,"first_name":"Gideon","last_name":"McCauley","email":"gmccauley1c@wordpress.com"} 50 | {"id":50,"first_name":"Rickie","last_name":"Zanitti","email":"rzanitti1d@jigsy.com"} 51 | {"id":51,"first_name":"Leodora","last_name":"Chaloner","email":"lchaloner1e@163.com"} 52 | {"id":52,"first_name":"Freida","last_name":"Strethill","email":"fstrethill1f@photobucket.com"} 53 | {"id":53,"first_name":"Noach","last_name":"Coot","email":"ncoot1g@omniture.com"} 54 | {"id":54,"first_name":"Shawn","last_name":"Booij","email":"sbooij1h@eepurl.com"} 55 | {"id":55,"first_name":"Currey","last_name":"Boyford","email":"cboyford1i@netvibes.com"} 56 | {"id":56,"first_name":"Kaitlin","last_name":"Ripon","email":"kripon1j@prnewswire.com"} 57 | {"id":57,"first_name":"Quintina","last_name":"Hallows","email":"qhallows1k@wikimedia.org"} 58 | {"id":58,"first_name":"Gallagher","last_name":"Degoey","email":"gdegoey1l@ox.ac.uk"} 59 | {"id":59,"first_name":"Bride","last_name":"Lodin","email":"blodin1m@storify.com"} 60 | {"id":60,"first_name":"Wilhelmine","last_name":"Longworth","email":"wlongworth1n@drupal.org"} 61 | {"id":61,"first_name":"Giacinta","last_name":"Gulliman","email":"ggulliman1o@ow.ly"} 62 | {"id":62,"first_name":"Whitney","last_name":"Swallwell","email":"wswallwell1p@businesswire.com"} 63 | {"id":63,"first_name":"Boris","last_name":"Larraway","email":"blarraway1q@disqus.com"} 64 | {"id":64,"first_name":"Guenevere","last_name":"Pierse","email":"gpierse1r@sourceforge.net"} 65 | {"id":65,"first_name":"Leela","last_name":"O'Carran","email":"locarran1s@telegraph.co.uk"} 66 | {"id":66,"first_name":"Anna-diana","last_name":"Marple","email":"amarple1t@unesco.org"} 67 | {"id":67,"first_name":"Irita","last_name":"Hayto","email":"ihayto1u@samsung.com"} 68 | {"id":68,"first_name":"Rance","last_name":"Urwen","email":"rurwen1v@t.co"} 69 | {"id":69,"first_name":"Mollie","last_name":"Frowing","email":"mfrowing1w@comcast.net"} 70 | {"id":70,"first_name":"Ellsworth","last_name":"Sandell","email":"esandell1x@google.com"} 71 | {"id":71,"first_name":"Jude","last_name":"Rooksby","email":"jrooksby1y@issuu.com"} 72 | {"id":72,"first_name":"Zahara","last_name":"Edworthie","email":"zedworthie1z@mysql.com"} 73 | {"id":73,"first_name":"Prentiss","last_name":"Meddings","email":"pmeddings20@deviantart.com"} 74 | {"id":74,"first_name":"Chrissie","last_name":"Lechmere","email":"clechmere21@abc.net.au"} 75 | {"id":75,"first_name":"Rosie","last_name":"Danels","email":"rdanels22@flavors.me"} 76 | {"id":76,"first_name":"Cchaddie","last_name":"Hatfield","email":"chatfield23@ehow.com"} 77 | {"id":77,"first_name":"Deana","last_name":"Goter","email":"dgoter24@yellowpages.com"} 78 | {"id":78,"first_name":"Agatha","last_name":"Witchard","email":"awitchard25@google.cn"} 79 | {"id":79,"first_name":"Rhiamon","last_name":"Bleckly","email":"rbleckly26@nymag.com"} 80 | {"id":80,"first_name":"Kellie","last_name":"Karpushkin","email":"kkarpushkin27@seattletimes.com"} 81 | {"id":81,"first_name":"Konstanze","last_name":"Ramsbottom","email":"kramsbottom28@gov.uk"} 82 | {"id":82,"first_name":"Doy","last_name":"Servant","email":"dservant29@amazon.de"} 83 | {"id":83,"first_name":"Marj","last_name":"Kenford","email":"mkenford2a@studiopress.com"} 84 | {"id":84,"first_name":"Amalia","last_name":"Hubbock","email":"ahubbock2b@upenn.edu"} 85 | {"id":85,"first_name":"Jeannie","last_name":"Vannah","email":"jvannah2c@sourceforge.net"} 86 | {"id":86,"first_name":"Janina","last_name":"Wigelsworth","email":"jwigelsworth2d@instagram.com"} 87 | {"id":87,"first_name":"Ermina","last_name":"Patshull","email":"epatshull2e@arstechnica.com"} 88 | {"id":88,"first_name":"Abbi","last_name":"Joseland","email":"ajoseland2f@discuz.net"} 89 | {"id":89,"first_name":"Lavinie","last_name":"Cosson","email":"lcosson2g@ucoz.com"} 90 | {"id":90,"first_name":"Noble","last_name":"Wyborn","email":"nwyborn2h@sun.com"} 91 | {"id":91,"first_name":"Lulita","last_name":"Tunnicliff","email":"ltunnicliff2i@dagondesign.com"} 92 | {"id":92,"first_name":"Debera","last_name":"Juris","email":"djuris2j@samsung.com"} 93 | {"id":93,"first_name":"Dania","last_name":"Heersema","email":"dheersema2k@ox.ac.uk"} 94 | {"id":94,"first_name":"Jacki","last_name":"Leveridge","email":"jleveridge2l@dropbox.com"} 95 | {"id":95,"first_name":"Zara","last_name":"Sainsbury-Brown","email":"zsainsburybrown2m@thetimes.co.uk"} 96 | {"id":96,"first_name":"Rhianna","last_name":"Pittson","email":"rpittson2n@ameblo.jp"} 97 | {"id":97,"first_name":"Bevon","last_name":"Rugge","email":"brugge2o@163.com"} 98 | {"id":98,"first_name":"Balduin","last_name":"Crosen","email":"bcrosen2p@nationalgeographic.com"} 99 | {"id":99,"first_name":"Jens","last_name":"Muspratt","email":"jmuspratt2q@wordpress.org"} 100 | {"id":100,"first_name":"Butch","last_name":"Rijkeseis","email":"brijkeseis2r@wordpress.com"} 101 | {"id":101,"first_name":"Garold","last_name":"Tincey","email":"gtincey2s@unesco.org"} 102 | {"id":102,"first_name":"Krishna","last_name":"Starkie","email":"kstarkie2t@gizmodo.com"} 103 | {"id":103,"first_name":"Thomasine","last_name":"Tickner","email":"ttickner2u@slashdot.org"} 104 | {"id":104,"first_name":"Tuesday","last_name":"Osmon","email":"tosmon2v@vkontakte.ru"} 105 | {"id":105,"first_name":"Elberta","last_name":"Ellsbury","email":"eellsbury2w@cmu.edu"} 106 | {"id":106,"first_name":"Rudyard","last_name":"Barrie","email":"rbarrie2x@wisc.edu"} 107 | {"id":107,"first_name":"Cash","last_name":"Cloutt","email":"ccloutt2y@twitter.com"} 108 | {"id":108,"first_name":"Jammal","last_name":"Bateman","email":"jbateman2z@va.gov"} 109 | {"id":109,"first_name":"Binnie","last_name":"Siddall","email":"bsiddall30@narod.ru"} 110 | {"id":110,"first_name":"Cirillo","last_name":"Stockbridge","email":"cstockbridge31@reddit.com"} 111 | {"id":111,"first_name":"Cherie","last_name":"Sommerlie","email":"csommerlie32@scientificamerican.com"} 112 | {"id":112,"first_name":"Jaquenette","last_name":"Autrie","email":"jautrie33@umich.edu"} 113 | {"id":113,"first_name":"Ellswerth","last_name":"Bethell","email":"ebethell34@adobe.com"} 114 | {"id":114,"first_name":"Earvin","last_name":"Millmore","email":"emillmore35@kickstarter.com"} 115 | {"id":115,"first_name":"Hall","last_name":"Ruddle","email":"hruddle36@tripod.com"} 116 | {"id":116,"first_name":"Eveleen","last_name":"O'Kennavain","email":"eokennavain37@squarespace.com"} 117 | {"id":117,"first_name":"Dillie","last_name":"Petrescu","email":"dpetrescu38@ibm.com"} 118 | {"id":118,"first_name":"Celestia","last_name":"Burwood","email":"cburwood39@oaic.gov.au"} 119 | {"id":119,"first_name":"Lynna","last_name":"Barnsdall","email":"lbarnsdall3a@marketwatch.com"} 120 | {"id":120,"first_name":"Jandy","last_name":"Noods","email":"jnoods3b@behance.net"} 121 | {"id":121,"first_name":"Guillemette","last_name":"Chinn","email":"gchinn3c@comcast.net"} 122 | {"id":122,"first_name":"Abagael","last_name":"Keenleyside","email":"akeenleyside3d@usatoday.com"} 123 | {"id":123,"first_name":"Arlan","last_name":"Kubczak","email":"akubczak3e@apache.org"} 124 | {"id":124,"first_name":"Tybi","last_name":"Flobert","email":"tflobert3f@cbsnews.com"} 125 | {"id":125,"first_name":"Hodge","last_name":"Champley","email":"hchampley3g@etsy.com"} 126 | {"id":126,"first_name":"Betta","last_name":"Navarijo","email":"bnavarijo3h@xrea.com"} 127 | {"id":127,"first_name":"Stacee","last_name":"Brunetti","email":"sbrunetti3i@artisteer.com"} 128 | {"id":128,"first_name":"Hurlee","last_name":"Bowstead","email":"hbowstead3j@mit.edu"} 129 | {"id":129,"first_name":"Linet","last_name":"Binnall","email":"lbinnall3k@blogger.com"} 130 | {"id":130,"first_name":"Daile","last_name":"Borrett","email":"dborrett3l@npr.org"} 131 | {"id":131,"first_name":"Kay","last_name":"Coneybeare","email":"kconeybeare3m@amazon.co.uk"} 132 | {"id":132,"first_name":"Menard","last_name":"Chatan","email":"mchatan3n@nih.gov"} 133 | {"id":133,"first_name":"Anthiathia","last_name":"Innman","email":"ainnman3o@wiley.com"} 134 | {"id":134,"first_name":"Lenka","last_name":"Polland","email":"lpolland3p@xing.com"} 135 | {"id":135,"first_name":"Allina","last_name":"Custed","email":"acusted3q@usa.gov"} 136 | {"id":136,"first_name":"Janessa","last_name":"Gerckens","email":"jgerckens3r@nyu.edu"} 137 | {"id":137,"first_name":"Magdalen","last_name":"Doerr","email":"mdoerr3s@lycos.com"} 138 | {"id":138,"first_name":"Pail","last_name":"Sellstrom","email":"psellstrom3t@sohu.com"} 139 | {"id":139,"first_name":"Lissy","last_name":"Pindell","email":"lpindell3u@dailymail.co.uk"} 140 | {"id":140,"first_name":"Beatriz","last_name":"Elintune","email":"belintune3v@cdc.gov"} 141 | {"id":141,"first_name":"Arlana","last_name":"Carik","email":"acarik3w@bigcartel.com"} 142 | {"id":142,"first_name":"Conny","last_name":"Anster","email":"canster3x@domainmarket.com"} 143 | {"id":143,"first_name":"Alvera","last_name":"Carn","email":"acarn3y@biblegateway.com"} 144 | {"id":144,"first_name":"Adriaens","last_name":"Farfoot","email":"afarfoot3z@dion.ne.jp"} 145 | {"id":145,"first_name":"Rosabelle","last_name":"Mardoll","email":"rmardoll40@i2i.jp"} 146 | {"id":146,"first_name":"Riki","last_name":"Orrett","email":"rorrett41@fda.gov"} 147 | {"id":147,"first_name":"Zorah","last_name":"Jaime","email":"zjaime42@xing.com"} 148 | {"id":148,"first_name":"Godwin","last_name":"Birkinshaw","email":"gbirkinshaw43@mail.ru"} 149 | {"id":149,"first_name":"Karoly","last_name":"Cowl","email":"kcowl44@rambler.ru"} 150 | {"id":150,"first_name":"Myrtle","last_name":"Gostling","email":"mgostling45@psu.edu"} 151 | {"id":151,"first_name":"Matthew","last_name":"Shird","email":"mshird46@linkedin.com"} 152 | {"id":152,"first_name":"Tanner","last_name":"Kubelka","email":"tkubelka47@state.tx.us"} 153 | {"id":153,"first_name":"Cosimo","last_name":"Broune","email":"cbroune48@sogou.com"} 154 | {"id":154,"first_name":"Rafa","last_name":"Vear","email":"rvear49@theglobeandmail.com"} 155 | {"id":155,"first_name":"Emmalynn","last_name":"Elcomb","email":"eelcomb4a@cam.ac.uk"} 156 | {"id":156,"first_name":"Karolina","last_name":"Mayler","email":"kmayler4b@furl.net"} 157 | {"id":157,"first_name":"Serene","last_name":"Piers","email":"spiers4c@etsy.com"} 158 | {"id":158,"first_name":"Garnet","last_name":"Reynault","email":"greynault4d@trellian.com"} 159 | {"id":159,"first_name":"Decca","last_name":"Kauscher","email":"dkauscher4e@eepurl.com"} 160 | {"id":160,"first_name":"Olga","last_name":"Willas","email":"owillas4f@npr.org"} 161 | {"id":161,"first_name":"Neil","last_name":"Chatel","email":"nchatel4g@nifty.com"} 162 | {"id":162,"first_name":"Jim","last_name":"Terrelly","email":"jterrelly4h@360.cn"} 163 | {"id":163,"first_name":"Ximenez","last_name":"Saffen","email":"xsaffen4i@deliciousdays.com"} 164 | {"id":164,"first_name":"Kandace","last_name":"Skitt","email":"kskitt4j@webs.com"} 165 | {"id":165,"first_name":"Dinny","last_name":"Borman","email":"dborman4k@issuu.com"} 166 | {"id":166,"first_name":"Wolfy","last_name":"McVanamy","email":"wmcvanamy4l@msn.com"} 167 | {"id":167,"first_name":"Tito","last_name":"Orlton","email":"torlton4m@discuz.net"} 168 | {"id":168,"first_name":"Leia","last_name":"Evelyn","email":"levelyn4n@dagondesign.com"} 169 | {"id":169,"first_name":"Kamila","last_name":"Jeste","email":"kjeste4o@imgur.com"} 170 | {"id":170,"first_name":"Annissa","last_name":"Aitchinson","email":"aaitchinson4p@msn.com"} 171 | {"id":171,"first_name":"Zulema","last_name":"Pimme","email":"zpimme4q@lulu.com"} 172 | {"id":172,"first_name":"Nichole","last_name":"Nealand","email":"nnealand4r@arstechnica.com"} 173 | {"id":173,"first_name":"Barth","last_name":"Carver","email":"bcarver4s@bloomberg.com"} 174 | {"id":174,"first_name":"Theodosia","last_name":"Helkin","email":"thelkin4t@shinystat.com"} 175 | {"id":175,"first_name":"Sander","last_name":"Monkton","email":"smonkton4u@globo.com"} 176 | {"id":176,"first_name":"Claus","last_name":"Mattsson","email":"cmattsson4v@joomla.org"} 177 | {"id":177,"first_name":"Julianne","last_name":"Bettenay","email":"jbettenay4w@com.com"} 178 | {"id":178,"first_name":"Conant","last_name":"Da Costa","email":"cdacosta4x@cam.ac.uk"} 179 | {"id":179,"first_name":"Patten","last_name":"Goldby","email":"pgoldby4y@nasa.gov"} 180 | {"id":180,"first_name":"Courtenay","last_name":"Taft","email":"ctaft4z@indiegogo.com"} 181 | {"id":181,"first_name":"Kirsten","last_name":"Gore","email":"kgore50@angelfire.com"} 182 | {"id":182,"first_name":"Quincy","last_name":"Cosslett","email":"qcosslett51@netscape.com"} 183 | {"id":183,"first_name":"Sherri","last_name":"Marchenko","email":"smarchenko52@simplemachines.org"} 184 | {"id":184,"first_name":"Marianna","last_name":"Van Schafflaer","email":"mvanschafflaer53@ftc.gov"} 185 | {"id":185,"first_name":"Idalina","last_name":"Mullinger","email":"imullinger54@dot.gov"} 186 | {"id":186,"first_name":"Pauline","last_name":"Volk","email":"pvolk55@addtoany.com"} 187 | {"id":187,"first_name":"Joel","last_name":"Kaasman","email":"jkaasman56@youtube.com"} 188 | {"id":188,"first_name":"Tremaine","last_name":"Follin","email":"tfollin57@answers.com"} 189 | {"id":189,"first_name":"Dyane","last_name":"Shasnan","email":"dshasnan58@whitehouse.gov"} 190 | {"id":190,"first_name":"Deny","last_name":"Packe","email":"dpacke59@wordpress.com"} 191 | {"id":191,"first_name":"Danella","last_name":"Clifford","email":"dclifford5a@toplist.cz"} 192 | {"id":192,"first_name":"Melesa","last_name":"Ballach","email":"mballach5b@netscape.com"} 193 | {"id":193,"first_name":"Annabel","last_name":"Bragginton","email":"abragginton5c@de.vu"} 194 | {"id":194,"first_name":"Reagen","last_name":"Boullin","email":"rboullin5d@e-recht24.de"} 195 | {"id":195,"first_name":"Cassi","last_name":"Chieco","email":"cchieco5e@go.com"} 196 | {"id":196,"first_name":"Rollins","last_name":"Hurdiss","email":"rhurdiss5f@indiatimes.com"} 197 | {"id":197,"first_name":"Ole","last_name":"Martusov","email":"omartusov5g@washingtonpost.com"} 198 | {"id":198,"first_name":"Hillyer","last_name":"Godson","email":"hgodson5h@51.la"} 199 | {"id":199,"first_name":"Wat","last_name":"Trusdale","email":"wtrusdale5i@alexa.com"} 200 | {"id":200,"first_name":"Dotti","last_name":"MacClancey","email":"dmacclancey5j@51.la"} 201 | {"id":201,"first_name":"Cassius","last_name":"Vaughan-Hughes","email":"cvaughanhughes5k@pcworld.com"} 202 | {"id":202,"first_name":"Aleksandr","last_name":"Rossey","email":"arossey5l@imageshack.us"} 203 | {"id":203,"first_name":"Wakefield","last_name":"Goodhay","email":"wgoodhay5m@gov.uk"} 204 | {"id":204,"first_name":"Patrizio","last_name":"Loutheane","email":"ploutheane5n@goo.gl"} 205 | {"id":205,"first_name":"Dayna","last_name":"Blaylock","email":"dblaylock5o@fda.gov"} 206 | {"id":206,"first_name":"Ad","last_name":"Henken","email":"ahenken5p@wikimedia.org"} 207 | {"id":207,"first_name":"Selene","last_name":"Saunderson","email":"ssaunderson5q@over-blog.com"} 208 | {"id":208,"first_name":"Almeda","last_name":"Hlavecek","email":"ahlavecek5r@ted.com"} 209 | {"id":209,"first_name":"Jessamine","last_name":"Coaster","email":"jcoaster5s@ning.com"} 210 | {"id":210,"first_name":"Valry","last_name":"McCollum","email":"vmccollum5t@upenn.edu"} 211 | {"id":211,"first_name":"Cami","last_name":"Treherne","email":"ctreherne5u@istockphoto.com"} 212 | {"id":212,"first_name":"Bartholemy","last_name":"Tharme","email":"btharme5v@businessinsider.com"} 213 | {"id":213,"first_name":"Sallyann","last_name":"Selcraig","email":"sselcraig5w@pcworld.com"} 214 | {"id":214,"first_name":"Felipa","last_name":"Faichnie","email":"ffaichnie5x@jimdo.com"} 215 | {"id":215,"first_name":"Charis","last_name":"Lakenton","email":"clakenton5y@goo.gl"} 216 | {"id":216,"first_name":"Hildagard","last_name":"Klesse","email":"hklesse5z@washington.edu"} 217 | {"id":217,"first_name":"Zoe","last_name":"Doul","email":"zdoul60@imdb.com"} 218 | {"id":218,"first_name":"Mab","last_name":"Thorrold","email":"mthorrold61@freewebs.com"} 219 | {"id":219,"first_name":"Shay","last_name":"Pringer","email":"springer62@arizona.edu"} 220 | {"id":220,"first_name":"Sandi","last_name":"Petford","email":"spetford63@symantec.com"} 221 | {"id":221,"first_name":"Yuma","last_name":"Pilmer","email":"ypilmer64@sciencedaily.com"} 222 | {"id":222,"first_name":"Jaymee","last_name":"Bennen","email":"jbennen65@a8.net"} 223 | {"id":223,"first_name":"Chris","last_name":"Carwithim","email":"ccarwithim66@tripadvisor.com"} 224 | {"id":224,"first_name":"Denney","last_name":"Shillum","email":"dshillum67@hugedomains.com"} 225 | {"id":225,"first_name":"Odille","last_name":"Marshall","email":"omarshall68@aboutads.info"} 226 | {"id":226,"first_name":"Forrest","last_name":"MacMoyer","email":"fmacmoyer69@bbc.co.uk"} 227 | {"id":227,"first_name":"Matteo","last_name":"Millhill","email":"mmillhill6a@ibm.com"} 228 | {"id":228,"first_name":"Loni","last_name":"Kedie","email":"lkedie6b@reverbnation.com"} 229 | {"id":229,"first_name":"Roland","last_name":"Lipyeat","email":"rlipyeat6c@aol.com"} 230 | {"id":230,"first_name":"Merrick","last_name":"Catterell","email":"mcatterell6d@barnesandnoble.com"} 231 | {"id":231,"first_name":"Lucias","last_name":"Kadar","email":"lkadar6e@slideshare.net"} 232 | {"id":232,"first_name":"Koral","last_name":"Sendall","email":"ksendall6f@ted.com"} 233 | {"id":233,"first_name":"Pollyanna","last_name":"Asbrey","email":"pasbrey6g@salon.com"} 234 | {"id":234,"first_name":"Gorden","last_name":"Guinn","email":"gguinn6h@usa.gov"} 235 | {"id":235,"first_name":"Cal","last_name":"Nower","email":"cnower6i@cloudflare.com"} 236 | {"id":236,"first_name":"Waldon","last_name":"McGruar","email":"wmcgruar6j@sbwire.com"} 237 | {"id":237,"first_name":"Ginger","last_name":"Cheers","email":"gcheers6k@gnu.org"} 238 | {"id":238,"first_name":"Jeremiah","last_name":"Ivanitsa","email":"jivanitsa6l@mlb.com"} 239 | {"id":239,"first_name":"Lind","last_name":"Marcu","email":"lmarcu6m@twitpic.com"} 240 | {"id":240,"first_name":"Sigismond","last_name":"Emmer","email":"semmer6n@hatena.ne.jp"} 241 | {"id":241,"first_name":"Zedekiah","last_name":"Davidsen","email":"zdavidsen6o@google.ru"} 242 | {"id":242,"first_name":"Alex","last_name":"Formie","email":"aformie6p@loc.gov"} 243 | {"id":243,"first_name":"Reid","last_name":"Goodhall","email":"rgoodhall6q@loc.gov"} 244 | {"id":244,"first_name":"Gray","last_name":"Forge","email":"gforge6r@virginia.edu"} 245 | {"id":245,"first_name":"Dalston","last_name":"Batteson","email":"dbatteson6s@dailymail.co.uk"} 246 | {"id":246,"first_name":"Base","last_name":"Devey","email":"bdevey6t@cocolog-nifty.com"} 247 | {"id":247,"first_name":"Beret","last_name":"Bann","email":"bbann6u@pcworld.com"} 248 | {"id":248,"first_name":"Lois","last_name":"Dudney","email":"ldudney6v@blog.com"} 249 | {"id":249,"first_name":"Garth","last_name":"Renner","email":"grenner6w@wsj.com"} 250 | {"id":250,"first_name":"Dorette","last_name":"Baglan","email":"dbaglan6x@cisco.com"} 251 | {"id":251,"first_name":"Joe","last_name":"Painter","email":"jpainter6y@unblog.fr"} 252 | {"id":252,"first_name":"Emilie","last_name":"Radborn","email":"eradborn6z@geocities.jp"} 253 | {"id":253,"first_name":"Dehlia","last_name":"Betchley","email":"dbetchley70@slideshare.net"} 254 | {"id":254,"first_name":"Ertha","last_name":"Makepeace","email":"emakepeace71@samsung.com"} 255 | {"id":255,"first_name":"Brita","last_name":"Currie","email":"bcurrie72@jigsy.com"} 256 | {"id":256,"first_name":"Blisse","last_name":"Collimore","email":"bcollimore73@hhs.gov"} 257 | {"id":257,"first_name":"Stearn","last_name":"Tattersall","email":"stattersall74@youtu.be"} 258 | {"id":258,"first_name":"Randi","last_name":"Lambertini","email":"rlambertini75@dot.gov"} 259 | {"id":259,"first_name":"Beryle","last_name":"Aspray","email":"baspray76@biglobe.ne.jp"} 260 | {"id":260,"first_name":"Pansy","last_name":"Ricketts","email":"pricketts77@google.co.uk"} 261 | {"id":261,"first_name":"Jeniece","last_name":"Eveque","email":"jeveque78@ucoz.ru"} 262 | {"id":262,"first_name":"Kelsey","last_name":"Desorts","email":"kdesorts79@blog.com"} 263 | {"id":263,"first_name":"Cecilla","last_name":"Hunting","email":"chunting7a@rediff.com"} 264 | {"id":264,"first_name":"Robbie","last_name":"Rudeyeard","email":"rrudeyeard7b@twitpic.com"} 265 | {"id":265,"first_name":"Ronny","last_name":"Cloy","email":"rcloy7c@wufoo.com"} 266 | {"id":266,"first_name":"Fallon","last_name":"McGarrie","email":"fmcgarrie7d@domainmarket.com"} 267 | {"id":267,"first_name":"Andree","last_name":"Salazar","email":"asalazar7e@aol.com"} 268 | {"id":268,"first_name":"Terri","last_name":"Pentlow","email":"tpentlow7f@narod.ru"} 269 | {"id":269,"first_name":"Teodoro","last_name":"Guerrazzi","email":"tguerrazzi7g@trellian.com"} 270 | {"id":270,"first_name":"Ashton","last_name":"Kirimaa","email":"akirimaa7h@cdc.gov"} 271 | {"id":271,"first_name":"Nikolas","last_name":"Vidineev","email":"nvidineev7i@tuttocitta.it"} 272 | {"id":272,"first_name":"Myrtia","last_name":"Karsh","email":"mkarsh7j@wired.com"} 273 | {"id":273,"first_name":"Modesty","last_name":"Boissier","email":"mboissier7k@aol.com"} 274 | {"id":274,"first_name":"Cyndia","last_name":"Leemans","email":"cleemans7l@cornell.edu"} 275 | {"id":275,"first_name":"Shantee","last_name":"Maykin","email":"smaykin7m@wix.com"} 276 | {"id":276,"first_name":"Emmerich","last_name":"Gergus","email":"egergus7n@paypal.com"} 277 | {"id":277,"first_name":"Lindsey","last_name":"Chaulk","email":"lchaulk7o@sfgate.com"} 278 | {"id":278,"first_name":"Romona","last_name":"Murie","email":"rmurie7p@sun.com"} 279 | {"id":279,"first_name":"Bel","last_name":"Hitzschke","email":"bhitzschke7q@jugem.jp"} 280 | {"id":280,"first_name":"Hilton","last_name":"Haythorn","email":"hhaythorn7r@sciencedaily.com"} 281 | {"id":281,"first_name":"Lydie","last_name":"Heinrici","email":"lheinrici7s@cnbc.com"} 282 | {"id":282,"first_name":"Gwynne","last_name":"Harriman","email":"gharriman7t@linkedin.com"} 283 | {"id":283,"first_name":"Boy","last_name":"Abrahmson","email":"babrahmson7u@mit.edu"} 284 | {"id":284,"first_name":"Rayner","last_name":"Murrill","email":"rmurrill7v@freewebs.com"} 285 | {"id":285,"first_name":"Steward","last_name":"Lodovichi","email":"slodovichi7w@ucoz.com"} 286 | {"id":286,"first_name":"Zelig","last_name":"Guillet","email":"zguillet7x@vistaprint.com"} 287 | {"id":287,"first_name":"Merrily","last_name":"Millen","email":"mmillen7y@cam.ac.uk"} 288 | {"id":288,"first_name":"Raff","last_name":"Goold","email":"rgoold7z@canalblog.com"} 289 | {"id":289,"first_name":"Aland","last_name":"Richards","email":"arichards80@people.com.cn"} 290 | {"id":290,"first_name":"Ambrose","last_name":"Fanning","email":"afanning81@telegraph.co.uk"} 291 | {"id":291,"first_name":"Dolly","last_name":"McConnulty","email":"dmcconnulty82@pen.io"} 292 | {"id":292,"first_name":"Eleen","last_name":"Muffen","email":"emuffen83@reddit.com"} 293 | {"id":293,"first_name":"Rachele","last_name":"Cleminshaw","email":"rcleminshaw84@apache.org"} 294 | {"id":294,"first_name":"Royall","last_name":"Grierson","email":"rgrierson85@chron.com"} 295 | {"id":295,"first_name":"Goldie","last_name":"Bouskill","email":"gbouskill86@vkontakte.ru"} 296 | {"id":296,"first_name":"Padraic","last_name":"Manolov","email":"pmanolov87@163.com"} 297 | {"id":297,"first_name":"Olivie","last_name":"Corcut","email":"ocorcut88@nyu.edu"} 298 | {"id":298,"first_name":"Cly","last_name":"Peete","email":"cpeete89@feedburner.com"} 299 | {"id":299,"first_name":"Stanly","last_name":"Grieswood","email":"sgrieswood8a@google.it"} 300 | {"id":300,"first_name":"Cullin","last_name":"Hammatt","email":"chammatt8b@hostgator.com"} 301 | {"id":301,"first_name":"Talbert","last_name":"Lilliman","email":"tlilliman8c@wufoo.com"} 302 | {"id":302,"first_name":"Britteny","last_name":"Kubica","email":"bkubica8d@jiathis.com"} 303 | {"id":303,"first_name":"Leona","last_name":"Matthaus","email":"lmatthaus8e@chicagotribune.com"} 304 | {"id":304,"first_name":"Minda","last_name":"Emmerson","email":"memmerson8f@cnn.com"} 305 | {"id":305,"first_name":"Reinhard","last_name":"Dudderidge","email":"rdudderidge8g@twitter.com"} 306 | {"id":306,"first_name":"Ode","last_name":"Isaac","email":"oisaac8h@mashable.com"} 307 | {"id":307,"first_name":"Tannie","last_name":"Duffan","email":"tduffan8i@netlog.com"} 308 | {"id":308,"first_name":"Riccardo","last_name":"Heaney","email":"rheaney8j@g.co"} 309 | {"id":309,"first_name":"Leann","last_name":"Klimpt","email":"lklimpt8k@wsj.com"} 310 | {"id":310,"first_name":"Jacquelyn","last_name":"Reddle","email":"jreddle8l@prlog.org"} 311 | {"id":311,"first_name":"Pebrook","last_name":"Gladdor","email":"pgladdor8m@hp.com"} 312 | {"id":312,"first_name":"Devy","last_name":"Keers","email":"dkeers8n@theglobeandmail.com"} 313 | {"id":313,"first_name":"Em","last_name":"Bullock","email":"ebullock8o@theglobeandmail.com"} 314 | {"id":314,"first_name":"Catharine","last_name":"Rabbitt","email":"crabbitt8p@usnews.com"} 315 | {"id":315,"first_name":"Roderick","last_name":"Barette","email":"rbarette8q@icq.com"} 316 | {"id":316,"first_name":"Joshia","last_name":"MacIver","email":"jmaciver8r@biblegateway.com"} 317 | {"id":317,"first_name":"Jarrad","last_name":"Donnan","email":"jdonnan8s@is.gd"} 318 | {"id":318,"first_name":"Sophey","last_name":"Corriea","email":"scorriea8t@liveinternet.ru"} 319 | {"id":319,"first_name":"Aura","last_name":"Pancast","email":"apancast8u@google.com.hk"} 320 | {"id":320,"first_name":"Benedikta","last_name":"Billin","email":"bbillin8v@cmu.edu"} 321 | {"id":321,"first_name":"Hermine","last_name":"Bidgood","email":"hbidgood8w@businessweek.com"} 322 | {"id":322,"first_name":"Woody","last_name":"Sellack","email":"wsellack8x@hibu.com"} 323 | {"id":323,"first_name":"Wrennie","last_name":"Ivermee","email":"wivermee8y@tuttocitta.it"} 324 | {"id":324,"first_name":"Miranda","last_name":"Pyle","email":"mpyle8z@bbb.org"} 325 | {"id":325,"first_name":"Cathee","last_name":"Dowdeswell","email":"cdowdeswell90@unblog.fr"} 326 | {"id":326,"first_name":"Georgine","last_name":"Beesley","email":"gbeesley91@amazon.com"} 327 | {"id":327,"first_name":"Marmaduke","last_name":"Musprat","email":"mmusprat92@fda.gov"} 328 | {"id":328,"first_name":"Jermayne","last_name":"Lindro","email":"jlindro93@spotify.com"} 329 | {"id":329,"first_name":"Kris","last_name":"Tripe","email":"ktripe94@phoca.cz"} 330 | {"id":330,"first_name":"Ofella","last_name":"Antushev","email":"oantushev95@desdev.cn"} 331 | {"id":331,"first_name":"Tod","last_name":"Macia","email":"tmacia96@engadget.com"} 332 | {"id":332,"first_name":"Jelene","last_name":"Cecere","email":"jcecere97@51.la"} 333 | {"id":333,"first_name":"Britney","last_name":"Sanches","email":"bsanches98@princeton.edu"} 334 | {"id":334,"first_name":"Quinn","last_name":"Pirolini","email":"qpirolini99@oracle.com"} 335 | {"id":335,"first_name":"Costanza","last_name":"Wharby","email":"cwharby9a@shareasale.com"} 336 | {"id":336,"first_name":"Steven","last_name":"Edel","email":"sedel9b@google.com.au"} 337 | {"id":337,"first_name":"Quinton","last_name":"Simonnet","email":"qsimonnet9c@mail.ru"} 338 | {"id":338,"first_name":"Conroy","last_name":"Sorey","email":"csorey9d@mapy.cz"} 339 | {"id":339,"first_name":"Kacey","last_name":"Tweedy","email":"ktweedy9e@telegraph.co.uk"} 340 | {"id":340,"first_name":"Aubrie","last_name":"Oatley","email":"aoatley9f@amazon.com"} 341 | {"id":341,"first_name":"Gerhard","last_name":"Rizzolo","email":"grizzolo9g@ftc.gov"} 342 | {"id":342,"first_name":"Keenan","last_name":"Godier","email":"kgodier9h@harvard.edu"} 343 | {"id":343,"first_name":"Alard","last_name":"Tubridy","email":"atubridy9i@ask.com"} 344 | {"id":344,"first_name":"Nadine","last_name":"Naden","email":"nnaden9j@ca.gov"} 345 | {"id":345,"first_name":"Alessandro","last_name":"Timson","email":"atimson9k@gov.uk"} 346 | {"id":346,"first_name":"Mirella","last_name":"Shurville","email":"mshurville9l@google.co.uk"} 347 | {"id":347,"first_name":"Libbie","last_name":"Waterman","email":"lwaterman9m@abc.net.au"} 348 | {"id":348,"first_name":"Cordy","last_name":"Selesnick","email":"cselesnick9n@freewebs.com"} 349 | {"id":349,"first_name":"Gerrard","last_name":"Roney","email":"groney9o@xrea.com"} 350 | {"id":350,"first_name":"Paulita","last_name":"Giacomi","email":"pgiacomi9p@utexas.edu"} 351 | {"id":351,"first_name":"Martguerita","last_name":"Ceaser","email":"mceaser9q@toplist.cz"} 352 | {"id":352,"first_name":"Alexei","last_name":"Kellitt","email":"akellitt9r@joomla.org"} 353 | {"id":353,"first_name":"Domenico","last_name":"Byard","email":"dbyard9s@histats.com"} 354 | {"id":354,"first_name":"Herby","last_name":"Piele","email":"hpiele9t@edublogs.org"} 355 | {"id":355,"first_name":"Shaughn","last_name":"Ramsby","email":"sramsby9u@ning.com"} 356 | {"id":356,"first_name":"Britni","last_name":"Maginot","email":"bmaginot9v@walmart.com"} 357 | {"id":357,"first_name":"May","last_name":"Manshaw","email":"mmanshaw9w@slideshare.net"} 358 | {"id":358,"first_name":"Onofredo","last_name":"Corcut","email":"ocorcut9x@vistaprint.com"} 359 | {"id":359,"first_name":"Lincoln","last_name":"Mantrup","email":"lmantrup9y@yolasite.com"} 360 | {"id":360,"first_name":"Ora","last_name":"Kearton","email":"okearton9z@bravesites.com"} 361 | {"id":361,"first_name":"Gaylord","last_name":"Kulicke","email":"gkulickea0@pen.io"} 362 | {"id":362,"first_name":"Thibaut","last_name":"Easbie","email":"teasbiea1@amazonaws.com"} 363 | {"id":363,"first_name":"Doro","last_name":"Metts","email":"dmettsa2@tiny.cc"} 364 | {"id":364,"first_name":"Lon","last_name":"Breslane","email":"lbreslanea3@sciencedaily.com"} 365 | {"id":365,"first_name":"Coreen","last_name":"Coultass","email":"ccoultassa4@skyrock.com"} 366 | {"id":366,"first_name":"Donall","last_name":"Cusack","email":"dcusacka5@cyberchimps.com"} 367 | {"id":367,"first_name":"Derrek","last_name":"O'Sharry","email":"dosharrya6@cbslocal.com"} 368 | {"id":368,"first_name":"Barth","last_name":"Thieme","email":"bthiemea7@odnoklassniki.ru"} 369 | {"id":369,"first_name":"Wyatt","last_name":"Alderton","email":"waldertona8@whitehouse.gov"} 370 | {"id":370,"first_name":"Correna","last_name":"Colmore","email":"ccolmorea9@icio.us"} 371 | {"id":371,"first_name":"Kacy","last_name":"Weippert","email":"kweippertaa@devhub.com"} 372 | {"id":372,"first_name":"Trista","last_name":"Androsik","email":"tandrosikab@boston.com"} 373 | {"id":373,"first_name":"Joyan","last_name":"Abramski","email":"jabramskiac@gnu.org"} 374 | {"id":374,"first_name":"Rafi","last_name":"Garfield","email":"rgarfieldad@yellowpages.com"} 375 | {"id":375,"first_name":"Wilton","last_name":"Tankard","email":"wtankardae@networksolutions.com"} 376 | {"id":376,"first_name":"Noak","last_name":"Crielly","email":"ncriellyaf@guardian.co.uk"} 377 | {"id":377,"first_name":"Louisette","last_name":"Redrup","email":"lredrupag@phoca.cz"} 378 | {"id":378,"first_name":"Anneliese","last_name":"Pegram","email":"apegramah@vinaora.com"} 379 | {"id":379,"first_name":"Jenny","last_name":"Guirau","email":"jguirauai@sciencedirect.com"} 380 | {"id":380,"first_name":"Phaedra","last_name":"Plaistowe","email":"pplaistoweaj@usatoday.com"} 381 | {"id":381,"first_name":"Terri","last_name":"Mathew","email":"tmathewak@jigsy.com"} 382 | {"id":382,"first_name":"Allegra","last_name":"Wenn","email":"awennal@squidoo.com"} 383 | {"id":383,"first_name":"Davita","last_name":"Fergyson","email":"dfergysonam@wix.com"} 384 | {"id":384,"first_name":"Genovera","last_name":"Billinge","email":"gbillingean@edublogs.org"} 385 | {"id":385,"first_name":"Lyndsay","last_name":"Zuker","email":"lzukerao@npr.org"} 386 | {"id":386,"first_name":"Bess","last_name":"Ryrie","email":"bryrieap@cnbc.com"} 387 | {"id":387,"first_name":"Rena","last_name":"Orniz","email":"rornizaq@cargocollective.com"} 388 | {"id":388,"first_name":"Baudoin","last_name":"Walklate","email":"bwalklatear@uiuc.edu"} 389 | {"id":389,"first_name":"Cherri","last_name":"Pollicote","email":"cpollicoteas@state.tx.us"} 390 | {"id":390,"first_name":"Yanaton","last_name":"Knappitt","email":"yknappittat@ucoz.com"} 391 | {"id":391,"first_name":"Audi","last_name":"Izkovicz","email":"aizkoviczau@google.es"} 392 | {"id":392,"first_name":"Lewes","last_name":"Chilcott","email":"lchilcottav@amazonaws.com"} 393 | {"id":393,"first_name":"Mariquilla","last_name":"Pinck","email":"mpinckaw@example.com"} 394 | {"id":394,"first_name":"Lodovico","last_name":"Tadman","email":"ltadmanax@vk.com"} 395 | {"id":395,"first_name":"Yancey","last_name":"Beardsall","email":"ybeardsallay@printfriendly.com"} 396 | {"id":396,"first_name":"Matilda","last_name":"Fedorski","email":"mfedorskiaz@biglobe.ne.jp"} 397 | {"id":397,"first_name":"Kellen","last_name":"Cleveley","email":"kcleveleyb0@state.gov"} 398 | {"id":398,"first_name":"Dave","last_name":"Aglione","email":"daglioneb1@barnesandnoble.com"} 399 | {"id":399,"first_name":"Sanders","last_name":"Noades","email":"snoadesb2@wufoo.com"} 400 | {"id":400,"first_name":"Ingar","last_name":"Asser","email":"iasserb3@youku.com"} 401 | {"id":401,"first_name":"Sandie","last_name":"Gregore","email":"sgregoreb4@msu.edu"} 402 | {"id":402,"first_name":"Georgiana","last_name":"Statefield","email":"gstatefieldb5@kickstarter.com"} 403 | {"id":403,"first_name":"Jackquelin","last_name":"Frugier","email":"jfrugierb6@unicef.org"} 404 | {"id":404,"first_name":"Hillary","last_name":"Dallyn","email":"hdallynb7@loc.gov"} 405 | {"id":405,"first_name":"Townsend","last_name":"Syde","email":"tsydeb8@answers.com"} 406 | {"id":406,"first_name":"Rina","last_name":"Scurrah","email":"rscurrahb9@wunderground.com"} 407 | {"id":407,"first_name":"Frank","last_name":"Sheer","email":"fsheerba@howstuffworks.com"} 408 | {"id":408,"first_name":"Marice","last_name":"Bertie","email":"mbertiebb@senate.gov"} 409 | {"id":409,"first_name":"Cookie","last_name":"McMillan","email":"cmcmillanbc@webeden.co.uk"} 410 | {"id":410,"first_name":"Emmy","last_name":"Lauthian","email":"elauthianbd@dedecms.com"} 411 | {"id":411,"first_name":"Kory","last_name":"Francklin","email":"kfrancklinbe@furl.net"} 412 | {"id":412,"first_name":"Gardiner","last_name":"Senyard","email":"gsenyardbf@wikispaces.com"} 413 | {"id":413,"first_name":"Mercedes","last_name":"Kolczynski","email":"mkolczynskibg@posterous.com"} 414 | {"id":414,"first_name":"Myriam","last_name":"Saben","email":"msabenbh@wix.com"} 415 | {"id":415,"first_name":"Chevy","last_name":"Quinell","email":"cquinellbi@dyndns.org"} 416 | {"id":416,"first_name":"Ed","last_name":"Heddon","email":"eheddonbj@usda.gov"} 417 | {"id":417,"first_name":"Gerek","last_name":"Baddiley","email":"gbaddileybk@diigo.com"} 418 | {"id":418,"first_name":"Edgardo","last_name":"Careswell","email":"ecareswellbl@amazonaws.com"} 419 | {"id":419,"first_name":"Hunfredo","last_name":"Gibbard","email":"hgibbardbm@istockphoto.com"} 420 | {"id":420,"first_name":"Audie","last_name":"Siddle","email":"asiddlebn@squidoo.com"} 421 | {"id":421,"first_name":"Adey","last_name":"Kingsford","email":"akingsfordbo@telegraph.co.uk"} 422 | {"id":422,"first_name":"Ethelyn","last_name":"Vanyushkin","email":"evanyushkinbp@amazonaws.com"} 423 | {"id":423,"first_name":"Bron","last_name":"Edger","email":"bedgerbq@bandcamp.com"} 424 | {"id":424,"first_name":"Cathrine","last_name":"Arnaldo","email":"carnaldobr@imgur.com"} 425 | {"id":425,"first_name":"Rickie","last_name":"Yeskov","email":"ryeskovbs@slate.com"} 426 | {"id":426,"first_name":"Gale","last_name":"Choat","email":"gchoatbt@google.de"} 427 | {"id":427,"first_name":"Garik","last_name":"Leak","email":"gleakbu@privacy.gov.au"} 428 | {"id":428,"first_name":"Timofei","last_name":"Whiteoak","email":"twhiteoakbv@tinyurl.com"} 429 | {"id":429,"first_name":"Wally","last_name":"Caughan","email":"wcaughanbw@msu.edu"} 430 | {"id":430,"first_name":"Yancy","last_name":"Stealfox","email":"ystealfoxbx@berkeley.edu"} 431 | {"id":431,"first_name":"Dela","last_name":"Strong","email":"dstrongby@free.fr"} 432 | {"id":432,"first_name":"Dougie","last_name":"Tewnion","email":"dtewnionbz@discovery.com"} 433 | {"id":433,"first_name":"Kelly","last_name":"Frean","email":"kfreanc0@imageshack.us"} 434 | {"id":434,"first_name":"Connie","last_name":"Blaschek","email":"cblaschekc1@wikipedia.org"} 435 | {"id":435,"first_name":"Michell","last_name":"D'Ambrogio","email":"mdambrogioc2@sfgate.com"} 436 | {"id":436,"first_name":"Larine","last_name":"Comber","email":"lcomberc3@com.com"} 437 | {"id":437,"first_name":"Giacopo","last_name":"Linde","email":"glindec4@tripadvisor.com"} 438 | {"id":438,"first_name":"Debbi","last_name":"Whaley","email":"dwhaleyc5@studiopress.com"} 439 | {"id":439,"first_name":"Alva","last_name":"Matyasik","email":"amatyasikc6@gmpg.org"} 440 | {"id":440,"first_name":"Mead","last_name":"Andrini","email":"mandrinic7@arstechnica.com"} 441 | {"id":441,"first_name":"Esme","last_name":"Casetti","email":"ecasettic8@furl.net"} 442 | {"id":442,"first_name":"Barbara","last_name":"Piel","email":"bpielc9@addtoany.com"} 443 | {"id":443,"first_name":"Slade","last_name":"Coaker","email":"scoakerca@spiegel.de"} 444 | {"id":444,"first_name":"Read","last_name":"Wackley","email":"rwackleycb@va.gov"} 445 | {"id":445,"first_name":"Min","last_name":"Dunnet","email":"mdunnetcc@friendfeed.com"} 446 | {"id":446,"first_name":"Barbabra","last_name":"Taffarello","email":"btaffarellocd@samsung.com"} 447 | {"id":447,"first_name":"Sadie","last_name":"Stanlick","email":"sstanlickce@vistaprint.com"} 448 | {"id":448,"first_name":"Keefe","last_name":"Inglese","email":"kinglesecf@nationalgeographic.com"} 449 | {"id":449,"first_name":"Domenic","last_name":"Tomasek","email":"dtomasekcg@privacy.gov.au"} 450 | {"id":450,"first_name":"Felic","last_name":"Rydzynski","email":"frydzynskich@flickr.com"} 451 | {"id":451,"first_name":"Alfy","last_name":"Hamman","email":"ahammanci@slate.com"} 452 | {"id":452,"first_name":"Townie","last_name":"Tomini","email":"ttominicj@printfriendly.com"} 453 | {"id":453,"first_name":"Evangelia","last_name":"Badrick","email":"ebadrickck@facebook.com"} 454 | {"id":454,"first_name":"Caron","last_name":"Cornil","email":"ccornilcl@newsvine.com"} 455 | {"id":455,"first_name":"Ernie","last_name":"Reddin","email":"ereddincm@tmall.com"} 456 | {"id":456,"first_name":"Arley","last_name":"Wardall","email":"awardallcn@tripod.com"} 457 | {"id":457,"first_name":"Robinet","last_name":"Sam","email":"rsamco@upenn.edu"} 458 | {"id":458,"first_name":"Melisenda","last_name":"Timeby","email":"mtimebycp@shinystat.com"} 459 | {"id":459,"first_name":"Shantee","last_name":"Annes","email":"sannescq@va.gov"} 460 | {"id":460,"first_name":"Molli","last_name":"Mish","email":"mmishcr@dot.gov"} 461 | {"id":461,"first_name":"Merralee","last_name":"Vickerman","email":"mvickermancs@baidu.com"} 462 | {"id":462,"first_name":"Wilhelmina","last_name":"Heminsley","email":"wheminsleyct@is.gd"} 463 | {"id":463,"first_name":"Granville","last_name":"MacKeague","email":"gmackeaguecu@pbs.org"} 464 | {"id":464,"first_name":"Sean","last_name":"Loftus","email":"sloftuscv@psu.edu"} 465 | {"id":465,"first_name":"Nevins","last_name":"Gawke","email":"ngawkecw@stumbleupon.com"} 466 | {"id":466,"first_name":"Gunilla","last_name":"Lucock","email":"glucockcx@deviantart.com"} 467 | {"id":467,"first_name":"Haydon","last_name":"Fiddy","email":"hfiddycy@imgur.com"} 468 | {"id":468,"first_name":"Ema","last_name":"Salatino","email":"esalatinocz@sitemeter.com"} 469 | {"id":469,"first_name":"Valentin","last_name":"Yakovliv","email":"vyakovlivd0@furl.net"} 470 | {"id":470,"first_name":"Carri","last_name":"Saltern","email":"csalternd1@biblegateway.com"} 471 | {"id":471,"first_name":"Kristos","last_name":"Stanmore","email":"kstanmored2@4shared.com"} 472 | {"id":472,"first_name":"Adriena","last_name":"Bes","email":"abesd3@constantcontact.com"} 473 | {"id":473,"first_name":"Cristabel","last_name":"Bortolutti","email":"cbortoluttid4@pinterest.com"} 474 | {"id":474,"first_name":"Hersh","last_name":"Lock","email":"hlockd5@forbes.com"} 475 | {"id":475,"first_name":"Yoshi","last_name":"Marler","email":"ymarlerd6@free.fr"} 476 | {"id":476,"first_name":"Tremaine","last_name":"Librey","email":"tlibreyd7@trellian.com"} 477 | {"id":477,"first_name":"Inge","last_name":"Strawbridge","email":"istrawbridged8@barnesandnoble.com"} 478 | {"id":478,"first_name":"Pascal","last_name":"Carvill","email":"pcarvilld9@washington.edu"} 479 | {"id":479,"first_name":"Zabrina","last_name":"Ianitti","email":"zianittida@yellowpages.com"} 480 | {"id":480,"first_name":"Almeta","last_name":"Wessell","email":"awesselldb@bbb.org"} 481 | {"id":481,"first_name":"Crissie","last_name":"Troy","email":"ctroydc@rambler.ru"} 482 | {"id":482,"first_name":"Xena","last_name":"Frammingham","email":"xframminghamdd@t-online.de"} 483 | {"id":483,"first_name":"Zilvia","last_name":"Grinvalds","email":"zgrinvaldsde@example.com"} 484 | {"id":484,"first_name":"Brit","last_name":"Twelftree","email":"btwelftreedf@shop-pro.jp"} 485 | {"id":485,"first_name":"Brianne","last_name":"Johannes","email":"bjohannesdg@nymag.com"} 486 | {"id":486,"first_name":"Felicle","last_name":"MacRury","email":"fmacrurydh@jiathis.com"} 487 | {"id":487,"first_name":"Salli","last_name":"Chillingworth","email":"schillingworthdi@gravatar.com"} 488 | {"id":488,"first_name":"Merline","last_name":"Bodd","email":"mbodddj@yandex.ru"} 489 | {"id":489,"first_name":"Christian","last_name":"Pengelley","email":"cpengelleydk@flavors.me"} 490 | {"id":490,"first_name":"Dallas","last_name":"Sollowaye","email":"dsollowayedl@zdnet.com"} 491 | {"id":491,"first_name":"Matias","last_name":"Austen","email":"maustendm@ow.ly"} 492 | {"id":492,"first_name":"Carney","last_name":"Bergin","email":"cbergindn@tiny.cc"} 493 | {"id":493,"first_name":"Carol","last_name":"Vannikov","email":"cvannikovdo@oakley.com"} 494 | {"id":494,"first_name":"Gail","last_name":"Garwood","email":"ggarwooddp@cbc.ca"} 495 | {"id":495,"first_name":"Adela","last_name":"Baddam","email":"abaddamdq@blinklist.com"} 496 | {"id":496,"first_name":"Bogey","last_name":"Tomala","email":"btomaladr@samsung.com"} 497 | {"id":497,"first_name":"Annabel","last_name":"Pinsent","email":"apinsentds@yelp.com"} 498 | {"id":498,"first_name":"Marijn","last_name":"Trevarthen","email":"mtrevarthendt@google.ca"} 499 | {"id":499,"first_name":"Arabelle","last_name":"Corneliussen","email":"acorneliussendu@census.gov"} 500 | {"id":500,"first_name":"Ritchie","last_name":"Rosenblum","email":"rrosenblumdv@i2i.jp"} 501 | {"id":501,"first_name":"Marji","last_name":"Clarage","email":"mclaragedw@gravatar.com"} 502 | {"id":502,"first_name":"Yolanthe","last_name":"Doddemeade","email":"ydoddemeadedx@cpanel.net"} 503 | {"id":503,"first_name":"Larine","last_name":"Rodd","email":"lrodddy@ft.com"} 504 | {"id":504,"first_name":"Adolpho","last_name":"Bleasdale","email":"ableasdaledz@unicef.org"} 505 | {"id":505,"first_name":"Rriocard","last_name":"Roggeman","email":"rroggemane0@salon.com"} 506 | {"id":506,"first_name":"Sissie","last_name":"Ephgrave","email":"sephgravee1@wikipedia.org"} 507 | {"id":507,"first_name":"Shepherd","last_name":"Davidde","email":"sdaviddee2@wikimedia.org"} 508 | {"id":508,"first_name":"Cecilla","last_name":"Girt","email":"cgirte3@soundcloud.com"} 509 | {"id":509,"first_name":"Alanah","last_name":"Newtown","email":"anewtowne4@cocolog-nifty.com"} 510 | {"id":510,"first_name":"Marvin","last_name":"Duckhouse","email":"mduckhousee5@icq.com"} 511 | {"id":511,"first_name":"Esme","last_name":"Crouch","email":"ecrouche6@foxnews.com"} 512 | {"id":512,"first_name":"Cthrine","last_name":"Yelding","email":"cyeldinge7@stumbleupon.com"} 513 | {"id":513,"first_name":"Nolly","last_name":"Gude","email":"ngudee8@bing.com"} 514 | {"id":514,"first_name":"Kimball","last_name":"O' Mulderrig","email":"komulderrige9@newyorker.com"} 515 | {"id":515,"first_name":"Felicdad","last_name":"Mutlow","email":"fmutlowea@wunderground.com"} 516 | {"id":516,"first_name":"Sybila","last_name":"Kirke","email":"skirkeeb@w3.org"} 517 | {"id":517,"first_name":"Aubrey","last_name":"Horney","email":"ahorneyec@1688.com"} 518 | {"id":518,"first_name":"Prudy","last_name":"Hartles","email":"phartlesed@scribd.com"} 519 | {"id":519,"first_name":"Saw","last_name":"Olyunin","email":"solyuninee@google.it"} 520 | {"id":520,"first_name":"Pearline","last_name":"Fasham","email":"pfashamef@chron.com"} 521 | {"id":521,"first_name":"Gretta","last_name":"Vasilmanov","email":"gvasilmanoveg@godaddy.com"} 522 | {"id":522,"first_name":"Pearle","last_name":"Scougal","email":"pscougaleh@si.edu"} 523 | {"id":523,"first_name":"Marney","last_name":"Mariotte","email":"mmariotteei@newsvine.com"} 524 | {"id":524,"first_name":"Bamby","last_name":"Lockhart","email":"blockhartej@mayoclinic.com"} 525 | {"id":525,"first_name":"Miguela","last_name":"Baumadier","email":"mbaumadierek@go.com"} 526 | {"id":526,"first_name":"Lusa","last_name":"Bartalin","email":"lbartalinel@fc2.com"} 527 | {"id":527,"first_name":"Helene","last_name":"Parlott","email":"hparlottem@wikimedia.org"} 528 | {"id":528,"first_name":"Manuel","last_name":"Scallon","email":"mscallonen@apple.com"} 529 | {"id":529,"first_name":"Wendie","last_name":"O' Scallan","email":"woscallaneo@aboutads.info"} 530 | {"id":530,"first_name":"Benito","last_name":"Kerry","email":"bkerryep@cmu.edu"} 531 | {"id":531,"first_name":"Dorthy","last_name":"Skinner","email":"dskinnereq@ustream.tv"} 532 | {"id":532,"first_name":"Demetris","last_name":"Picton","email":"dpictoner@typepad.com"} 533 | {"id":533,"first_name":"Barrie","last_name":"Hurkett","email":"bhurkettes@mlb.com"} 534 | {"id":534,"first_name":"Lucretia","last_name":"Wherry","email":"lwherryet@amazon.com"} 535 | {"id":535,"first_name":"Molly","last_name":"Castagna","email":"mcastagnaeu@google.cn"} 536 | {"id":536,"first_name":"Waylin","last_name":"Chieco","email":"wchiecoev@youtube.com"} 537 | {"id":537,"first_name":"Bobinette","last_name":"Headingham","email":"bheadinghamew@intel.com"} 538 | {"id":538,"first_name":"Malinda","last_name":"Gerardi","email":"mgerardiex@samsung.com"} 539 | {"id":539,"first_name":"Rhodia","last_name":"Kenderdine","email":"rkenderdineey@arstechnica.com"} 540 | {"id":540,"first_name":"Saundra","last_name":"Brader","email":"sbraderez@msu.edu"} 541 | {"id":541,"first_name":"Mariana","last_name":"Buye","email":"mbuyef0@wikimedia.org"} 542 | {"id":542,"first_name":"Hagan","last_name":"Stoop","email":"hstoopf1@tripadvisor.com"} 543 | {"id":543,"first_name":"Marlene","last_name":"Keane","email":"mkeanef2@google.cn"} 544 | {"id":544,"first_name":"Sayer","last_name":"Eggar","email":"seggarf3@unicef.org"} 545 | {"id":545,"first_name":"Eve","last_name":"Allanson","email":"eallansonf4@china.com.cn"} 546 | {"id":546,"first_name":"Arielle","last_name":"Kytter","email":"akytterf5@spotify.com"} 547 | {"id":547,"first_name":"Deerdre","last_name":"Cabbell","email":"dcabbellf6@youtube.com"} 548 | {"id":548,"first_name":"Nathan","last_name":"Cromleholme","email":"ncromleholmef7@fema.gov"} 549 | {"id":549,"first_name":"Brion","last_name":"Recher","email":"brecherf8@usgs.gov"} 550 | {"id":550,"first_name":"Tiena","last_name":"Grealish","email":"tgrealishf9@mail.ru"} 551 | {"id":551,"first_name":"Dane","last_name":"Durtnal","email":"ddurtnalfa@latimes.com"} 552 | {"id":552,"first_name":"Bealle","last_name":"Lesurf","email":"blesurffb@vinaora.com"} 553 | {"id":553,"first_name":"Evangelina","last_name":"Lawrie","email":"elawriefc@ameblo.jp"} 554 | {"id":554,"first_name":"Svend","last_name":"Leel","email":"sleelfd@ucoz.ru"} 555 | {"id":555,"first_name":"Cristen","last_name":"Klimkov","email":"cklimkovfe@about.me"} 556 | {"id":556,"first_name":"Devon","last_name":"Lanchbury","email":"dlanchburyff@umn.edu"} 557 | {"id":557,"first_name":"Rem","last_name":"Cordes","email":"rcordesfg@yolasite.com"} 558 | {"id":558,"first_name":"Romy","last_name":"Mattiazzi","email":"rmattiazzifh@craigslist.org"} 559 | {"id":559,"first_name":"Wit","last_name":"Attenborrow","email":"wattenborrowfi@auda.org.au"} 560 | {"id":560,"first_name":"Nanni","last_name":"Studders","email":"nstuddersfj@yandex.ru"} 561 | {"id":561,"first_name":"Mandie","last_name":"Trembley","email":"mtrembleyfk@gizmodo.com"} 562 | {"id":562,"first_name":"Babette","last_name":"Clemmens","email":"bclemmensfl@acquirethisname.com"} 563 | {"id":563,"first_name":"Ban","last_name":"Bennion","email":"bbennionfm@github.com"} 564 | {"id":564,"first_name":"Gail","last_name":"Trevon","email":"gtrevonfn@upenn.edu"} 565 | {"id":565,"first_name":"Karine","last_name":"Alexandrescu","email":"kalexandrescufo@globo.com"} 566 | {"id":566,"first_name":"Sabrina","last_name":"Klaes","email":"sklaesfp@example.com"} 567 | {"id":567,"first_name":"Adriane","last_name":"Figgins","email":"afigginsfq@cafepress.com"} 568 | {"id":568,"first_name":"Terese","last_name":"Goldney","email":"tgoldneyfr@purevolume.com"} 569 | {"id":569,"first_name":"Ashlie","last_name":"Bowling","email":"abowlingfs@dion.ne.jp"} 570 | {"id":570,"first_name":"Rivi","last_name":"Laurenz","email":"rlaurenzft@php.net"} 571 | {"id":571,"first_name":"Phillip","last_name":"Longstaffe","email":"plongstaffefu@goo.gl"} 572 | {"id":572,"first_name":"Adrian","last_name":"Jewes","email":"ajewesfv@elpais.com"} 573 | {"id":573,"first_name":"Muriel","last_name":"Ladlow","email":"mladlowfw@vkontakte.ru"} 574 | {"id":574,"first_name":"Ange","last_name":"Habishaw","email":"ahabishawfx@walmart.com"} 575 | {"id":575,"first_name":"Kennith","last_name":"Olive","email":"kolivefy@tamu.edu"} 576 | {"id":576,"first_name":"Vonnie","last_name":"Eastbrook","email":"veastbrookfz@merriam-webster.com"} 577 | {"id":577,"first_name":"Doralyn","last_name":"Scarbarrow","email":"dscarbarrowg0@gnu.org"} 578 | {"id":578,"first_name":"Adams","last_name":"Sharpley","email":"asharpleyg1@blogger.com"} 579 | {"id":579,"first_name":"Gilberte","last_name":"Camamile","email":"gcamamileg2@dailymail.co.uk"} 580 | {"id":580,"first_name":"Emylee","last_name":"Siley","email":"esileyg3@friendfeed.com"} 581 | {"id":581,"first_name":"Hanan","last_name":"Falvey","email":"hfalveyg4@springer.com"} 582 | {"id":582,"first_name":"Nerty","last_name":"Marqyes","email":"nmarqyesg5@thetimes.co.uk"} 583 | {"id":583,"first_name":"Neysa","last_name":"Mossdale","email":"nmossdaleg6@de.vu"} 584 | {"id":584,"first_name":"Allayne","last_name":"Crookall","email":"acrookallg7@amazon.de"} 585 | {"id":585,"first_name":"Ally","last_name":"Lesly","email":"aleslyg8@howstuffworks.com"} 586 | {"id":586,"first_name":"Saraann","last_name":"Rosson","email":"srossong9@e-recht24.de"} 587 | {"id":587,"first_name":"Marissa","last_name":"Garn","email":"mgarnga@360.cn"} 588 | {"id":588,"first_name":"Rusty","last_name":"Jenteau","email":"rjenteaugb@spiegel.de"} 589 | {"id":589,"first_name":"Daria","last_name":"Danilchenko","email":"ddanilchenkogc@networkadvertising.org"} 590 | {"id":590,"first_name":"Emmi","last_name":"Duny","email":"edunygd@dedecms.com"} 591 | {"id":591,"first_name":"Felice","last_name":"Manser","email":"fmanserge@bizjournals.com"} 592 | {"id":592,"first_name":"Domeniga","last_name":"Garrand","email":"dgarrandgf@goo.ne.jp"} 593 | {"id":593,"first_name":"Tani","last_name":"Bampton","email":"tbamptongg@huffingtonpost.com"} 594 | {"id":594,"first_name":"Paige","last_name":"Holdren","email":"pholdrengh@hugedomains.com"} 595 | {"id":595,"first_name":"Junia","last_name":"Stoppe","email":"jstoppegi@slideshare.net"} 596 | {"id":596,"first_name":"Krista","last_name":"Hardwidge","email":"khardwidgegj@people.com.cn"} 597 | {"id":597,"first_name":"Theodosia","last_name":"Bleddon","email":"tbleddongk@geocities.jp"} 598 | {"id":598,"first_name":"Esmaria","last_name":"Gomez","email":"egomezgl@slate.com"} 599 | {"id":599,"first_name":"Karisa","last_name":"Dearnley","email":"kdearnleygm@nyu.edu"} 600 | {"id":600,"first_name":"Dud","last_name":"Cuddon","email":"dcuddongn@youku.com"} 601 | {"id":601,"first_name":"Daile","last_name":"Mylechreest","email":"dmylechreestgo@ox.ac.uk"} 602 | {"id":602,"first_name":"Josselyn","last_name":"Chaplyn","email":"jchaplyngp@shop-pro.jp"} 603 | {"id":603,"first_name":"Klarrisa","last_name":"Balnave","email":"kbalnavegq@microsoft.com"} 604 | {"id":604,"first_name":"Nolie","last_name":"Petters","email":"npettersgr@opera.com"} 605 | {"id":605,"first_name":"Bruno","last_name":"Vautin","email":"bvautings@earthlink.net"} 606 | {"id":606,"first_name":"Ki","last_name":"Stucke","email":"kstuckegt@newyorker.com"} 607 | {"id":607,"first_name":"Jerad","last_name":"MacGettigen","email":"jmacgettigengu@nyu.edu"} 608 | {"id":608,"first_name":"Waverly","last_name":"Gwyer","email":"wgwyergv@sogou.com"} 609 | {"id":609,"first_name":"Norene","last_name":"Detloff","email":"ndetloffgw@istockphoto.com"} 610 | {"id":610,"first_name":"Alfonse","last_name":"Mont","email":"amontgx@mozilla.org"} 611 | {"id":611,"first_name":"Shepperd","last_name":"Duffy","email":"sduffygy@jigsy.com"} 612 | {"id":612,"first_name":"Petronille","last_name":"Doughty","email":"pdoughtygz@prweb.com"} 613 | {"id":613,"first_name":"Northrop","last_name":"Stent","email":"nstenth0@nytimes.com"} 614 | {"id":614,"first_name":"Marline","last_name":"Ferrar","email":"mferrarh1@utexas.edu"} 615 | {"id":615,"first_name":"Brenda","last_name":"Sancho","email":"bsanchoh2@com.com"} 616 | {"id":616,"first_name":"Leeanne","last_name":"Candlish","email":"lcandlishh3@merriam-webster.com"} 617 | {"id":617,"first_name":"Brianna","last_name":"Starford","email":"bstarfordh4@theguardian.com"} 618 | {"id":618,"first_name":"Leroi","last_name":"Smissen","email":"lsmissenh5@loc.gov"} 619 | {"id":619,"first_name":"Nev","last_name":"Belvin","email":"nbelvinh6@dedecms.com"} 620 | {"id":620,"first_name":"Kellen","last_name":"Strowlger","email":"kstrowlgerh7@about.com"} 621 | {"id":621,"first_name":"Ninette","last_name":"Kerton","email":"nkertonh8@google.com.au"} 622 | {"id":622,"first_name":"Ruby","last_name":"Klewer","email":"rklewerh9@engadget.com"} 623 | {"id":623,"first_name":"Berte","last_name":"Joynes","email":"bjoynesha@icq.com"} 624 | {"id":624,"first_name":"Jacob","last_name":"Houseago","email":"jhouseagohb@ocn.ne.jp"} 625 | {"id":625,"first_name":"Wandis","last_name":"Souster","email":"wsousterhc@ask.com"} 626 | {"id":626,"first_name":"Kelila","last_name":"Guillon","email":"kguillonhd@vistaprint.com"} 627 | {"id":627,"first_name":"Gretchen","last_name":"Mellsop","email":"gmellsophe@nationalgeographic.com"} 628 | {"id":628,"first_name":"Agnese","last_name":"Rider","email":"ariderhf@bloglovin.com"} 629 | {"id":629,"first_name":"Sabina","last_name":"Spilsburie","email":"sspilsburiehg@who.int"} 630 | {"id":630,"first_name":"Aubrie","last_name":"Patey","email":"apateyhh@linkedin.com"} 631 | {"id":631,"first_name":"Wolfie","last_name":"Sommerville","email":"wsommervillehi@domainmarket.com"} 632 | {"id":632,"first_name":"Anderea","last_name":"Haversum","email":"ahaversumhj@pbs.org"} 633 | {"id":633,"first_name":"Alessandro","last_name":"Giovani","email":"agiovanihk@cbslocal.com"} 634 | {"id":634,"first_name":"Arlette","last_name":"Dulwich","email":"adulwichhl@google.nl"} 635 | {"id":635,"first_name":"Reamonn","last_name":"Flintiff","email":"rflintiffhm@wikia.com"} 636 | {"id":636,"first_name":"Lowe","last_name":"Redding","email":"lreddinghn@naver.com"} 637 | {"id":637,"first_name":"Dannel","last_name":"Lloyds","email":"dlloydsho@odnoklassniki.ru"} 638 | {"id":638,"first_name":"Gasparo","last_name":"Curtoys","email":"gcurtoyshp@tuttocitta.it"} 639 | {"id":639,"first_name":"Larry","last_name":"Shatliff","email":"lshatliffhq@mayoclinic.com"} 640 | {"id":640,"first_name":"Faina","last_name":"Dauby","email":"fdaubyhr@washingtonpost.com"} 641 | {"id":641,"first_name":"Kara-lynn","last_name":"Prise","email":"kprisehs@live.com"} 642 | {"id":642,"first_name":"Garry","last_name":"Patinkin","email":"gpatinkinht@goo.gl"} 643 | {"id":643,"first_name":"Bryan","last_name":"Eyrl","email":"beyrlhu@indiegogo.com"} 644 | {"id":644,"first_name":"Dominick","last_name":"Goracci","email":"dgoraccihv@cdbaby.com"} 645 | {"id":645,"first_name":"Sabine","last_name":"Dami","email":"sdamihw@php.net"} 646 | {"id":646,"first_name":"Simeon","last_name":"Czajka","email":"sczajkahx@auda.org.au"} 647 | {"id":647,"first_name":"Bertrando","last_name":"Ostler","email":"bostlerhy@networksolutions.com"} 648 | {"id":648,"first_name":"Guillaume","last_name":"Halahan","email":"ghalahanhz@weibo.com"} 649 | {"id":649,"first_name":"Artus","last_name":"Shotton","email":"ashottoni0@goodreads.com"} 650 | {"id":650,"first_name":"Thurston","last_name":"Privett","email":"tprivetti1@goo.ne.jp"} 651 | {"id":651,"first_name":"Dagny","last_name":"Handford","email":"dhandfordi2@homestead.com"} 652 | {"id":652,"first_name":"Bathsheba","last_name":"Pordall","email":"bpordalli3@howstuffworks.com"} 653 | {"id":653,"first_name":"Gwynne","last_name":"Vallens","email":"gvallensi4@feedburner.com"} 654 | {"id":654,"first_name":"Faun","last_name":"McMurrugh","email":"fmcmurrughi5@merriam-webster.com"} 655 | {"id":655,"first_name":"Kerry","last_name":"Gooding","email":"kgoodingi6@macromedia.com"} 656 | {"id":656,"first_name":"Sol","last_name":"Baskerfield","email":"sbaskerfieldi7@amazon.co.uk"} 657 | {"id":657,"first_name":"Belvia","last_name":"Risebrow","email":"brisebrowi8@netlog.com"} 658 | {"id":658,"first_name":"Kelila","last_name":"Stocken","email":"kstockeni9@xinhuanet.com"} 659 | {"id":659,"first_name":"Raff","last_name":"Kelland","email":"rkellandia@technorati.com"} 660 | {"id":660,"first_name":"Sophi","last_name":"Bengough","email":"sbengoughib@booking.com"} 661 | {"id":661,"first_name":"Annmarie","last_name":"Ivins","email":"aivinsic@wikispaces.com"} 662 | {"id":662,"first_name":"Nettie","last_name":"Camings","email":"ncamingsid@amazon.co.jp"} 663 | {"id":663,"first_name":"Ted","last_name":"Alcoran","email":"talcoranie@hhs.gov"} 664 | {"id":664,"first_name":"Tim","last_name":"Murden","email":"tmurdenif@jugem.jp"} 665 | {"id":665,"first_name":"Latrina","last_name":"Baines","email":"lbainesig@sphinn.com"} 666 | {"id":666,"first_name":"Sanders","last_name":"Crampsey","email":"scrampseyih@cocolog-nifty.com"} 667 | {"id":667,"first_name":"Laurena","last_name":"Bristowe","email":"lbristoweii@sciencedaily.com"} 668 | {"id":668,"first_name":"Brose","last_name":"Blanchet","email":"bblanchetij@archive.org"} 669 | {"id":669,"first_name":"Jacintha","last_name":"Kimmel","email":"jkimmelik@psu.edu"} 670 | {"id":670,"first_name":"Nat","last_name":"Hast","email":"nhastil@ifeng.com"} 671 | {"id":671,"first_name":"Ealasaid","last_name":"MacHoste","email":"emachosteim@nps.gov"} 672 | {"id":672,"first_name":"Merralee","last_name":"Phippen","email":"mphippenin@usgs.gov"} 673 | {"id":673,"first_name":"Donella","last_name":"Sanzio","email":"dsanzioio@theatlantic.com"} 674 | {"id":674,"first_name":"Giorgi","last_name":"Chaff","email":"gchaffip@taobao.com"} 675 | {"id":675,"first_name":"Bennie","last_name":"Smallsman","email":"bsmallsmaniq@webmd.com"} 676 | {"id":676,"first_name":"Georgie","last_name":"Crole","email":"gcroleir@dot.gov"} 677 | {"id":677,"first_name":"Petra","last_name":"Chappelow","email":"pchappelowis@tmall.com"} 678 | {"id":678,"first_name":"Dalton","last_name":"Wewell","email":"dwewellit@tiny.cc"} 679 | {"id":679,"first_name":"Kinnie","last_name":"Guilaem","email":"kguilaemiu@ezinearticles.com"} 680 | {"id":680,"first_name":"Merci","last_name":"Doyle","email":"mdoyleiv@boston.com"} 681 | {"id":681,"first_name":"Constance","last_name":"Tilson","email":"ctilsoniw@usda.gov"} 682 | {"id":682,"first_name":"Paige","last_name":"Sygroves","email":"psygrovesix@sfgate.com"} 683 | {"id":683,"first_name":"Rutherford","last_name":"Ughi","email":"rughiiy@webeden.co.uk"} 684 | {"id":684,"first_name":"Jamil","last_name":"Crighton","email":"jcrightoniz@china.com.cn"} 685 | {"id":685,"first_name":"Gaspard","last_name":"Lockner","email":"glocknerj0@hao123.com"} 686 | {"id":686,"first_name":"Sindee","last_name":"Beade","email":"sbeadej1@sbwire.com"} 687 | {"id":687,"first_name":"Irina","last_name":"Perren","email":"iperrenj2@oracle.com"} 688 | {"id":688,"first_name":"Annis","last_name":"Asker","email":"aaskerj3@whitehouse.gov"} 689 | {"id":689,"first_name":"Ingram","last_name":"MacGiany","email":"imacgianyj4@blogspot.com"} 690 | {"id":690,"first_name":"Germaine","last_name":"Maltby","email":"gmaltbyj5@usda.gov"} 691 | {"id":691,"first_name":"Berkly","last_name":"Prazor","email":"bprazorj6@flickr.com"} 692 | {"id":692,"first_name":"Ferguson","last_name":"Kyffin","email":"fkyffinj7@goodreads.com"} 693 | {"id":693,"first_name":"Winonah","last_name":"Furze","email":"wfurzej8@alexa.com"} 694 | {"id":694,"first_name":"Merwin","last_name":"Ionnidis","email":"mionnidisj9@slashdot.org"} 695 | {"id":695,"first_name":"Jerrilee","last_name":"Speerman","email":"jspeermanja@tumblr.com"} 696 | {"id":696,"first_name":"Leslie","last_name":"Mulvy","email":"lmulvyjb@bravesites.com"} 697 | {"id":697,"first_name":"Eryn","last_name":"Stoffel","email":"estoffeljc@infoseek.co.jp"} 698 | {"id":698,"first_name":"Ladonna","last_name":"Bosward","email":"lboswardjd@php.net"} 699 | {"id":699,"first_name":"Giustino","last_name":"Killelea","email":"gkilleleaje@statcounter.com"} 700 | {"id":700,"first_name":"Dillie","last_name":"Angell","email":"dangelljf@weather.com"} 701 | {"id":701,"first_name":"Henri","last_name":"Arnison","email":"harnisonjg@bluehost.com"} 702 | {"id":702,"first_name":"Fina","last_name":"Joules","email":"fjoulesjh@webmd.com"} 703 | {"id":703,"first_name":"Elden","last_name":"Shortan","email":"eshortanji@github.com"} 704 | {"id":704,"first_name":"Vevay","last_name":"Imison","email":"vimisonjj@slideshare.net"} 705 | {"id":705,"first_name":"Marcellina","last_name":"Jagg","email":"mjaggjk@dmoz.org"} 706 | {"id":706,"first_name":"Evin","last_name":"Lamacraft","email":"elamacraftjl@dagondesign.com"} 707 | {"id":707,"first_name":"Marcel","last_name":"Edy","email":"medyjm@aboutads.info"} 708 | {"id":708,"first_name":"Orlan","last_name":"Drei","email":"odreijn@oaic.gov.au"} 709 | {"id":709,"first_name":"Egbert","last_name":"Shillington","email":"eshillingtonjo@simplemachines.org"} 710 | {"id":710,"first_name":"Opal","last_name":"Oldnall","email":"ooldnalljp@indiatimes.com"} 711 | {"id":711,"first_name":"Brianne","last_name":"Penticost","email":"bpenticostjq@webmd.com"} 712 | {"id":712,"first_name":"Pip","last_name":"Blaney","email":"pblaneyjr@weather.com"} 713 | {"id":713,"first_name":"Michaella","last_name":"Goldsberry","email":"mgoldsberryjs@dell.com"} 714 | {"id":714,"first_name":"Jerrilee","last_name":"Paridge","email":"jparidgejt@wikipedia.org"} 715 | {"id":715,"first_name":"Joelly","last_name":"Knightley","email":"jknightleyju@joomla.org"} 716 | {"id":716,"first_name":"Eloisa","last_name":"Lee","email":"eleejv@abc.net.au"} 717 | {"id":717,"first_name":"Andee","last_name":"Boscott","email":"aboscottjw@angelfire.com"} 718 | {"id":718,"first_name":"Menard","last_name":"Bazley","email":"mbazleyjx@si.edu"} 719 | {"id":719,"first_name":"Hadria","last_name":"MacDonough","email":"hmacdonoughjy@blogspot.com"} 720 | {"id":720,"first_name":"Demetrius","last_name":"Ghelardi","email":"dghelardijz@4shared.com"} 721 | {"id":721,"first_name":"Ingra","last_name":"Boshard","email":"iboshardk0@forbes.com"} 722 | {"id":722,"first_name":"Shelley","last_name":"Cradoc","email":"scradock1@google.nl"} 723 | {"id":723,"first_name":"Bertrando","last_name":"Wurst","email":"bwurstk2@hhs.gov"} 724 | {"id":724,"first_name":"Duky","last_name":"Moresby","email":"dmoresbyk3@w3.org"} 725 | {"id":725,"first_name":"Lynda","last_name":"Matzeitis","email":"lmatzeitisk4@bing.com"} 726 | {"id":726,"first_name":"Galvan","last_name":"Challen","email":"gchallenk5@nasa.gov"} 727 | {"id":727,"first_name":"Bette-ann","last_name":"Lytlle","email":"blytllek6@linkedin.com"} 728 | {"id":728,"first_name":"Henderson","last_name":"Tonsley","email":"htonsleyk7@wikipedia.org"} 729 | {"id":729,"first_name":"Daffi","last_name":"Welch","email":"dwelchk8@geocities.com"} 730 | {"id":730,"first_name":"Enrique","last_name":"Emig","email":"eemigk9@digg.com"} 731 | {"id":731,"first_name":"Darnall","last_name":"Tupman","email":"dtupmanka@indiegogo.com"} 732 | {"id":732,"first_name":"Vicki","last_name":"Trayes","email":"vtrayeskb@phpbb.com"} 733 | {"id":733,"first_name":"Quintus","last_name":"Sancroft","email":"qsancroftkc@ycombinator.com"} 734 | {"id":734,"first_name":"Karola","last_name":"Mille","email":"kmillekd@ustream.tv"} 735 | {"id":735,"first_name":"Aretha","last_name":"Callum","email":"acallumke@washingtonpost.com"} 736 | {"id":736,"first_name":"Karisa","last_name":"Stainer","email":"kstainerkf@nsw.gov.au"} 737 | {"id":737,"first_name":"Carine","last_name":"Goom","email":"cgoomkg@whitehouse.gov"} 738 | {"id":738,"first_name":"Town","last_name":"Hannan","email":"thannankh@harvard.edu"} 739 | {"id":739,"first_name":"Micheal","last_name":"Arnaudin","email":"marnaudinki@theatlantic.com"} 740 | {"id":740,"first_name":"Shaun","last_name":"Prendergrass","email":"sprendergrasskj@mapquest.com"} 741 | {"id":741,"first_name":"Chastity","last_name":"Waszczyk","email":"cwaszczykkk@gravatar.com"} 742 | {"id":742,"first_name":"Christy","last_name":"Northey","email":"cnortheykl@nymag.com"} 743 | {"id":743,"first_name":"Melamie","last_name":"Triggel","email":"mtriggelkm@myspace.com"} 744 | {"id":744,"first_name":"Duffy","last_name":"Albrook","email":"dalbrookkn@oakley.com"} 745 | {"id":745,"first_name":"Viv","last_name":"Millwall","email":"vmillwallko@technorati.com"} 746 | {"id":746,"first_name":"Abie","last_name":"Cacacie","email":"acacaciekp@reference.com"} 747 | {"id":747,"first_name":"Micah","last_name":"Howden","email":"mhowdenkq@youtube.com"} 748 | {"id":748,"first_name":"Gerladina","last_name":"Sheeran","email":"gsheerankr@soundcloud.com"} 749 | {"id":749,"first_name":"Reidar","last_name":"Withur","email":"rwithurks@1688.com"} 750 | {"id":750,"first_name":"Killy","last_name":"Stroulger","email":"kstroulgerkt@webs.com"} 751 | {"id":751,"first_name":"Penelope","last_name":"Foli","email":"pfoliku@ucoz.ru"} 752 | {"id":752,"first_name":"Pascal","last_name":"Blethyn","email":"pblethynkv@people.com.cn"} 753 | {"id":753,"first_name":"Jacobo","last_name":"Renols","email":"jrenolskw@nhs.uk"} 754 | {"id":754,"first_name":"Donelle","last_name":"Jarrell","email":"djarrellkx@about.com"} 755 | {"id":755,"first_name":"Hakim","last_name":"Pietrzyk","email":"hpietrzykky@123-reg.co.uk"} 756 | {"id":756,"first_name":"Fania","last_name":"Hallick","email":"fhallickkz@state.gov"} 757 | {"id":757,"first_name":"Boote","last_name":"Gomersal","email":"bgomersall0@virginia.edu"} 758 | {"id":758,"first_name":"Luis","last_name":"Valler","email":"lvallerl1@zimbio.com"} 759 | {"id":759,"first_name":"Shana","last_name":"Vittel","email":"svittell2@virginia.edu"} 760 | {"id":760,"first_name":"Onofredo","last_name":"Philliphs","email":"ophilliphsl3@vistaprint.com"} 761 | {"id":761,"first_name":"Osmond","last_name":"Moulson","email":"omoulsonl4@fema.gov"} 762 | {"id":762,"first_name":"Ly","last_name":"Greenan","email":"lgreenanl5@ucla.edu"} 763 | {"id":763,"first_name":"Mervin","last_name":"Koop","email":"mkoopl6@mediafire.com"} 764 | {"id":764,"first_name":"Ferrel","last_name":"Redfearn","email":"fredfearnl7@nyu.edu"} 765 | {"id":765,"first_name":"Robby","last_name":"Huglin","email":"rhuglinl8@nature.com"} 766 | {"id":766,"first_name":"Kendre","last_name":"Youle","email":"kyoulel9@domainmarket.com"} 767 | {"id":767,"first_name":"Windy","last_name":"Rubel","email":"wrubella@telegraph.co.uk"} 768 | {"id":768,"first_name":"Crystal","last_name":"Carmichael","email":"ccarmichaellb@admin.ch"} 769 | {"id":769,"first_name":"Agata","last_name":"Penner","email":"apennerlc@tinyurl.com"} 770 | {"id":770,"first_name":"Odey","last_name":"Morse","email":"omorseld@wired.com"} 771 | {"id":771,"first_name":"Siegfried","last_name":"Glackin","email":"sglackinle@hao123.com"} 772 | {"id":772,"first_name":"Norbie","last_name":"Reiners","email":"nreinerslf@cmu.edu"} 773 | {"id":773,"first_name":"Kipp","last_name":"Lowdes","email":"klowdeslg@privacy.gov.au"} 774 | {"id":774,"first_name":"Dyann","last_name":"Francklyn","email":"dfrancklynlh@google.com.br"} 775 | {"id":775,"first_name":"Gwennie","last_name":"McGlynn","email":"gmcglynnli@live.com"} 776 | {"id":776,"first_name":"Viviyan","last_name":"Erdis","email":"verdislj@clickbank.net"} 777 | {"id":777,"first_name":"Hallie","last_name":"Sherewood","email":"hsherewoodlk@trellian.com"} 778 | {"id":778,"first_name":"Redd","last_name":"Stenton","email":"rstentonll@infoseek.co.jp"} 779 | {"id":779,"first_name":"Wendall","last_name":"Bath","email":"wbathlm@upenn.edu"} 780 | {"id":780,"first_name":"Corilla","last_name":"Zanetello","email":"czanetelloln@sfgate.com"} 781 | {"id":781,"first_name":"Christye","last_name":"Dracey","email":"cdraceylo@qq.com"} 782 | {"id":782,"first_name":"Nester","last_name":"Farleigh","email":"nfarleighlp@usgs.gov"} 783 | {"id":783,"first_name":"Langsdon","last_name":"Haggard","email":"lhaggardlq@reddit.com"} 784 | {"id":784,"first_name":"Chev","last_name":"Hay","email":"chaylr@timesonline.co.uk"} 785 | {"id":785,"first_name":"Burlie","last_name":"Cutchee","email":"bcutcheels@dagondesign.com"} 786 | {"id":786,"first_name":"Darya","last_name":"Mitchinson","email":"dmitchinsonlt@bizjournals.com"} 787 | {"id":787,"first_name":"Bibi","last_name":"Skitral","email":"bskitrallu@homestead.com"} 788 | {"id":788,"first_name":"Kaylee","last_name":"Olivo","email":"kolivolv@census.gov"} 789 | {"id":789,"first_name":"Lenore","last_name":"Roseblade","email":"lrosebladelw@ning.com"} 790 | {"id":790,"first_name":"Tulley","last_name":"Gonthard","email":"tgonthardlx@bloomberg.com"} 791 | {"id":791,"first_name":"Olav","last_name":"Galfour","email":"ogalfourly@icq.com"} 792 | {"id":792,"first_name":"Nicolas","last_name":"Margarson","email":"nmargarsonlz@free.fr"} 793 | {"id":793,"first_name":"Reine","last_name":"Klugman","email":"rklugmanm0@fc2.com"} 794 | {"id":794,"first_name":"Gnni","last_name":"Grewcock","email":"ggrewcockm1@clickbank.net"} 795 | {"id":795,"first_name":"Lorain","last_name":"Crossby","email":"lcrossbym2@cdc.gov"} 796 | {"id":796,"first_name":"Angil","last_name":"Toll","email":"atollm3@deliciousdays.com"} 797 | {"id":797,"first_name":"Georgianne","last_name":"Piotrowski","email":"gpiotrowskim4@goo.gl"} 798 | {"id":798,"first_name":"Sheelagh","last_name":"Orwin","email":"sorwinm5@xing.com"} 799 | {"id":799,"first_name":"Ingrid","last_name":"Dallon","email":"idallonm6@noaa.gov"} 800 | {"id":800,"first_name":"Tab","last_name":"Thomasson","email":"tthomassonm7@columbia.edu"} 801 | {"id":801,"first_name":"Merridie","last_name":"Scandroot","email":"mscandrootm8@wsj.com"} 802 | {"id":802,"first_name":"Morty","last_name":"MacDunleavy","email":"mmacdunleavym9@canalblog.com"} 803 | {"id":803,"first_name":"Lind","last_name":"Jordanson","email":"ljordansonma@tinypic.com"} 804 | {"id":804,"first_name":"Field","last_name":"Iiannoni","email":"fiiannonimb@over-blog.com"} 805 | {"id":805,"first_name":"Sammie","last_name":"Whimper","email":"swhimpermc@imageshack.us"} 806 | {"id":806,"first_name":"Davy","last_name":"Darthe","email":"ddarthemd@netvibes.com"} 807 | {"id":807,"first_name":"Salli","last_name":"Binstead","email":"sbinsteadme@hubpages.com"} 808 | {"id":808,"first_name":"Betty","last_name":"Chown","email":"bchownmf@flavors.me"} 809 | {"id":809,"first_name":"Dinnie","last_name":"Ilyushkin","email":"dilyushkinmg@archive.org"} 810 | {"id":810,"first_name":"Renee","last_name":"Daymond","email":"rdaymondmh@accuweather.com"} 811 | {"id":811,"first_name":"Eddie","last_name":"Duley","email":"eduleymi@lulu.com"} 812 | {"id":812,"first_name":"Izak","last_name":"Latour","email":"ilatourmj@narod.ru"} 813 | {"id":813,"first_name":"Maura","last_name":"Stuckford","email":"mstuckfordmk@nymag.com"} 814 | {"id":814,"first_name":"Sven","last_name":"Clampin","email":"sclampinml@163.com"} 815 | {"id":815,"first_name":"Marlon","last_name":"Bischoff","email":"mbischoffmm@wsj.com"} 816 | {"id":816,"first_name":"Gustave","last_name":"Hardbattle","email":"ghardbattlemn@mozilla.com"} 817 | {"id":817,"first_name":"Alaine","last_name":"Dietzler","email":"adietzlermo@timesonline.co.uk"} 818 | {"id":818,"first_name":"Alisa","last_name":"Ghirardi","email":"aghirardimp@blogspot.com"} 819 | {"id":819,"first_name":"Irena","last_name":"Goskar","email":"igoskarmq@archive.org"} 820 | {"id":820,"first_name":"Eugenius","last_name":"Taillant","email":"etaillantmr@linkedin.com"} 821 | {"id":821,"first_name":"Patton","last_name":"Garbert","email":"pgarbertms@drupal.org"} 822 | {"id":822,"first_name":"Callie","last_name":"Kubera","email":"ckuberamt@ed.gov"} 823 | {"id":823,"first_name":"Carrissa","last_name":"Duplain","email":"cduplainmu@bing.com"} 824 | {"id":824,"first_name":"Rena","last_name":"Thominga","email":"rthomingamv@cocolog-nifty.com"} 825 | {"id":825,"first_name":"Adriaens","last_name":"Lye","email":"alyemw@wikipedia.org"} 826 | {"id":826,"first_name":"Robena","last_name":"Tackett","email":"rtackettmx@360.cn"} 827 | {"id":827,"first_name":"Yvon","last_name":"Emanuele","email":"yemanuelemy@odnoklassniki.ru"} 828 | {"id":828,"first_name":"Marcel","last_name":"Beckinsall","email":"mbeckinsallmz@blinklist.com"} 829 | {"id":829,"first_name":"Donaugh","last_name":"Gaitskill","email":"dgaitskilln0@cyberchimps.com"} 830 | {"id":830,"first_name":"Daloris","last_name":"Leman","email":"dlemann1@etsy.com"} 831 | {"id":831,"first_name":"Cad","last_name":"Fermin","email":"cferminn2@blogs.com"} 832 | {"id":832,"first_name":"Brigida","last_name":"Hurry","email":"bhurryn3@wunderground.com"} 833 | {"id":833,"first_name":"Carlene","last_name":"Duns","email":"cdunsn4@timesonline.co.uk"} 834 | {"id":834,"first_name":"King","last_name":"Giblett","email":"kgiblettn5@bbc.co.uk"} 835 | {"id":835,"first_name":"Emelita","last_name":"Benito","email":"ebeniton6@dell.com"} 836 | {"id":836,"first_name":"Valentine","last_name":"MacCaughey","email":"vmaccaugheyn7@dropbox.com"} 837 | {"id":837,"first_name":"Donnell","last_name":"Pitcock","email":"dpitcockn8@eepurl.com"} 838 | {"id":838,"first_name":"Dasie","last_name":"Goburn","email":"dgoburnn9@sciencedirect.com"} 839 | {"id":839,"first_name":"Berty","last_name":"Klulicek","email":"bklulicekna@artisteer.com"} 840 | {"id":840,"first_name":"Franzen","last_name":"Pindred","email":"fpindrednb@dropbox.com"} 841 | {"id":841,"first_name":"Othilia","last_name":"Mattia","email":"omattianc@hugedomains.com"} 842 | {"id":842,"first_name":"Analise","last_name":"Absolom","email":"aabsolomnd@over-blog.com"} 843 | {"id":843,"first_name":"Bella","last_name":"Cowndley","email":"bcowndleyne@networksolutions.com"} 844 | {"id":844,"first_name":"Rich","last_name":"Sweedland","email":"rsweedlandnf@studiopress.com"} 845 | {"id":845,"first_name":"Sinclair","last_name":"Bonsale","email":"sbonsaleng@icq.com"} 846 | {"id":846,"first_name":"Thurston","last_name":"Blumsom","email":"tblumsomnh@foxnews.com"} 847 | {"id":847,"first_name":"Howey","last_name":"Dufoure","email":"hdufoureni@geocities.jp"} 848 | {"id":848,"first_name":"Hannie","last_name":"Kryzhov","email":"hkryzhovnj@deliciousdays.com"} 849 | {"id":849,"first_name":"Anneliese","last_name":"Winchcum","email":"awinchcumnk@ifeng.com"} 850 | {"id":850,"first_name":"Ronda","last_name":"Chicotti","email":"rchicottinl@liveinternet.ru"} 851 | {"id":851,"first_name":"Lacy","last_name":"Dennis","email":"ldennisnm@paypal.com"} 852 | {"id":852,"first_name":"Chery","last_name":"Leasor","email":"cleasornn@ning.com"} 853 | {"id":853,"first_name":"Melli","last_name":"Gowler","email":"mgowlerno@prlog.org"} 854 | {"id":854,"first_name":"Audi","last_name":"Ratnage","email":"aratnagenp@sbwire.com"} 855 | {"id":855,"first_name":"Marci","last_name":"Cato","email":"mcatonq@vinaora.com"} 856 | {"id":856,"first_name":"Verena","last_name":"de Guerre","email":"vdeguerrenr@latimes.com"} 857 | {"id":857,"first_name":"Guglielmo","last_name":"Wiltshaw","email":"gwiltshawns@macromedia.com"} 858 | {"id":858,"first_name":"Thatch","last_name":"Palin","email":"tpalinnt@elegantthemes.com"} 859 | {"id":859,"first_name":"Amaleta","last_name":"Godthaab","email":"agodthaabnu@yellowpages.com"} 860 | {"id":860,"first_name":"Danna","last_name":"Bertome","email":"dbertomenv@jimdo.com"} 861 | {"id":861,"first_name":"Terrance","last_name":"Lade","email":"tladenw@php.net"} 862 | {"id":862,"first_name":"Arlie","last_name":"Runsey","email":"arunseynx@icq.com"} 863 | {"id":863,"first_name":"Ericha","last_name":"Tamas","email":"etamasny@businesswire.com"} 864 | {"id":864,"first_name":"Annissa","last_name":"Carine","email":"acarinenz@sitemeter.com"} 865 | {"id":865,"first_name":"Isaac","last_name":"Conybear","email":"iconybearo0@imgur.com"} 866 | {"id":866,"first_name":"Susy","last_name":"Perris","email":"sperriso1@patch.com"} 867 | {"id":867,"first_name":"Michele","last_name":"Malcher","email":"mmalchero2@google.com"} 868 | {"id":868,"first_name":"Benn","last_name":"Serot","email":"bseroto3@altervista.org"} 869 | {"id":869,"first_name":"Hewett","last_name":"Smoote","email":"hsmooteo4@dot.gov"} 870 | {"id":870,"first_name":"Renie","last_name":"Rallings","email":"rrallingso5@ox.ac.uk"} 871 | {"id":871,"first_name":"Sammy","last_name":"Trew","email":"strewo6@slideshare.net"} 872 | {"id":872,"first_name":"Enos","last_name":"Fisbburne","email":"efisbburneo7@webs.com"} 873 | {"id":873,"first_name":"Yancy","last_name":"Rookwell","email":"yrookwello8@sina.com.cn"} 874 | {"id":874,"first_name":"Iolande","last_name":"Shillingford","email":"ishillingfordo9@forbes.com"} 875 | {"id":875,"first_name":"Yorker","last_name":"Downes","email":"ydownesoa@addthis.com"} 876 | {"id":876,"first_name":"Laina","last_name":"Jaulme","email":"ljaulmeob@elpais.com"} 877 | {"id":877,"first_name":"Reta","last_name":"Argont","email":"rargontoc@harvard.edu"} 878 | {"id":878,"first_name":"Mirabelle","last_name":"Schach","email":"mschachod@pen.io"} 879 | {"id":879,"first_name":"Nataline","last_name":"Cornish","email":"ncornishoe@bbb.org"} 880 | {"id":880,"first_name":"Rab","last_name":"MacPaden","email":"rmacpadenof@ameblo.jp"} 881 | {"id":881,"first_name":"Cheryl","last_name":"Blaske","email":"cblaskeog@slate.com"} 882 | {"id":882,"first_name":"Walton","last_name":"Fishburn","email":"wfishburnoh@china.com.cn"} 883 | {"id":883,"first_name":"Leoine","last_name":"Habercham","email":"lhaberchamoi@dailymotion.com"} 884 | {"id":884,"first_name":"Caria","last_name":"Lemmers","email":"clemmersoj@prweb.com"} 885 | {"id":885,"first_name":"Ebenezer","last_name":"Renny","email":"erennyok@smugmug.com"} 886 | {"id":886,"first_name":"Max","last_name":"Overy","email":"moveryol@elegantthemes.com"} 887 | {"id":887,"first_name":"Patience","last_name":"Bilyard","email":"pbilyardom@hexun.com"} 888 | {"id":888,"first_name":"Aubree","last_name":"Burdekin","email":"aburdekinon@house.gov"} 889 | {"id":889,"first_name":"Grover","last_name":"Trivett","email":"gtrivettoo@stumbleupon.com"} 890 | {"id":890,"first_name":"Brittani","last_name":"Durkin","email":"bdurkinop@chronoengine.com"} 891 | {"id":891,"first_name":"Mair","last_name":"Denyer","email":"mdenyeroq@livejournal.com"} 892 | {"id":892,"first_name":"Antons","last_name":"Pond-Jones","email":"apondjonesor@netvibes.com"} 893 | {"id":893,"first_name":"Terri","last_name":"Edgeworth","email":"tedgeworthos@youtu.be"} 894 | {"id":894,"first_name":"Rikki","last_name":"Schust","email":"rschustot@hatena.ne.jp"} 895 | {"id":895,"first_name":"Emanuel","last_name":"Magee","email":"emageeou@shutterfly.com"} 896 | {"id":896,"first_name":"Leodora","last_name":"Dewick","email":"ldewickov@ycombinator.com"} 897 | {"id":897,"first_name":"Lani","last_name":"Caskey","email":"lcaskeyow@nyu.edu"} 898 | {"id":898,"first_name":"Ashla","last_name":"Ordemann","email":"aordemannox@shareasale.com"} 899 | {"id":899,"first_name":"Bran","last_name":"Glidder","email":"bglidderoy@dyndns.org"} 900 | {"id":900,"first_name":"Ricardo","last_name":"Sarle","email":"rsarleoz@msu.edu"} 901 | {"id":901,"first_name":"Marcille","last_name":"Strevens","email":"mstrevensp0@house.gov"} 902 | {"id":902,"first_name":"Corbet","last_name":"Thurner","email":"cthurnerp1@theatlantic.com"} 903 | {"id":903,"first_name":"Peirce","last_name":"Poveleye","email":"ppoveleyep2@so-net.ne.jp"} 904 | {"id":904,"first_name":"Berti","last_name":"Baldacco","email":"bbaldaccop3@guardian.co.uk"} 905 | {"id":905,"first_name":"Jemima","last_name":"Menichino","email":"jmenichinop4@mashable.com"} 906 | {"id":906,"first_name":"Hobart","last_name":"Dawtry","email":"hdawtryp5@nationalgeographic.com"} 907 | {"id":907,"first_name":"Tiena","last_name":"Giannazzo","email":"tgiannazzop6@goodreads.com"} 908 | {"id":908,"first_name":"Buck","last_name":"Sturley","email":"bsturleyp7@apache.org"} 909 | {"id":909,"first_name":"Corly","last_name":"Sidgwick","email":"csidgwickp8@elegantthemes.com"} 910 | {"id":910,"first_name":"Lynnea","last_name":"Bezzant","email":"lbezzantp9@rakuten.co.jp"} 911 | {"id":911,"first_name":"Skipp","last_name":"Shepperd","email":"sshepperdpa@apple.com"} 912 | {"id":912,"first_name":"Jeffry","last_name":"Grierson","email":"jgriersonpb@nih.gov"} 913 | {"id":913,"first_name":"Killian","last_name":"Grzegorzewski","email":"kgrzegorzewskipc@homestead.com"} 914 | {"id":914,"first_name":"Phebe","last_name":"Holtaway","email":"pholtawaypd@tinypic.com"} 915 | {"id":915,"first_name":"Morgan","last_name":"Glader","email":"mgladerpe@newsvine.com"} 916 | {"id":916,"first_name":"Dallon","last_name":"Hamshere","email":"dhamsherepf@geocities.com"} 917 | {"id":917,"first_name":"Sullivan","last_name":"Jorden","email":"sjordenpg@umich.edu"} 918 | {"id":918,"first_name":"Barbara","last_name":"Simak","email":"bsimakph@nsw.gov.au"} 919 | {"id":919,"first_name":"Arlyne","last_name":"Guiduzzi","email":"aguiduzzipi@pcworld.com"} 920 | {"id":920,"first_name":"Raff","last_name":"Tremathick","email":"rtremathickpj@webs.com"} 921 | {"id":921,"first_name":"Ailsun","last_name":"Castelain","email":"acastelainpk@engadget.com"} 922 | {"id":922,"first_name":"Zelda","last_name":"Malt","email":"zmaltpl@icio.us"} 923 | {"id":923,"first_name":"Chanda","last_name":"Loram","email":"clorampm@about.me"} 924 | {"id":924,"first_name":"Kiel","last_name":"Binford","email":"kbinfordpn@latimes.com"} 925 | {"id":925,"first_name":"Sawyer","last_name":"Lesslie","email":"slessliepo@webnode.com"} 926 | {"id":926,"first_name":"Billi","last_name":"Hunte","email":"bhuntepp@bravesites.com"} 927 | {"id":927,"first_name":"Thaxter","last_name":"Mellows","email":"tmellowspq@twitpic.com"} 928 | {"id":928,"first_name":"Shani","last_name":"Djokic","email":"sdjokicpr@fastcompany.com"} 929 | {"id":929,"first_name":"Hardy","last_name":"Ambrogelli","email":"hambrogellips@goo.ne.jp"} 930 | {"id":930,"first_name":"Antonie","last_name":"Georgins","email":"ageorginspt@seesaa.net"} 931 | {"id":931,"first_name":"Ennis","last_name":"Schuck","email":"eschuckpu@globo.com"} 932 | {"id":932,"first_name":"Jermayne","last_name":"Reeson","email":"jreesonpv@networkadvertising.org"} 933 | {"id":933,"first_name":"Claudio","last_name":"Stener","email":"cstenerpw@dyndns.org"} 934 | {"id":934,"first_name":"Stella","last_name":"McLeoid","email":"smcleoidpx@bigcartel.com"} 935 | {"id":935,"first_name":"Steven","last_name":"Warby","email":"swarbypy@cnn.com"} 936 | {"id":936,"first_name":"Oby","last_name":"Prangle","email":"opranglepz@dedecms.com"} 937 | {"id":937,"first_name":"Kellsie","last_name":"Roberson","email":"krobersonq0@skyrock.com"} 938 | {"id":938,"first_name":"Chiquia","last_name":"De la croix","email":"cdelacroixq1@virginia.edu"} 939 | {"id":939,"first_name":"Richie","last_name":"Pyett","email":"rpyettq2@hexun.com"} 940 | {"id":940,"first_name":"Darb","last_name":"Pavitt","email":"dpavittq3@bbb.org"} 941 | {"id":941,"first_name":"Gwenneth","last_name":"Champken","email":"gchampkenq4@stanford.edu"} 942 | {"id":942,"first_name":"Roger","last_name":"Lghan","email":"rlghanq5@cdbaby.com"} 943 | {"id":943,"first_name":"Aurelia","last_name":"Golt","email":"agoltq6@opera.com"} 944 | {"id":944,"first_name":"Stefa","last_name":"Polini","email":"spoliniq7@elpais.com"} 945 | {"id":945,"first_name":"Elden","last_name":"Kuschek","email":"ekuschekq8@imageshack.us"} 946 | {"id":946,"first_name":"Lucille","last_name":"Davidy","email":"ldavidyq9@paginegialle.it"} 947 | {"id":947,"first_name":"Amelina","last_name":"Rabson","email":"arabsonqa@ihg.com"} 948 | {"id":948,"first_name":"Rustin","last_name":"Pickrill","email":"rpickrillqb@dedecms.com"} 949 | {"id":949,"first_name":"Nicol","last_name":"Gargett","email":"ngargettqc@mit.edu"} 950 | {"id":950,"first_name":"Malachi","last_name":"Chipman","email":"mchipmanqd@harvard.edu"} 951 | {"id":951,"first_name":"Zebulon","last_name":"Wackly","email":"zwacklyqe@diigo.com"} 952 | {"id":952,"first_name":"Casi","last_name":"Cosans","email":"ccosansqf@pbs.org"} 953 | {"id":953,"first_name":"Gustavo","last_name":"Hampton","email":"ghamptonqg@tinyurl.com"} 954 | {"id":954,"first_name":"Yves","last_name":"Dineen","email":"ydineenqh@godaddy.com"} 955 | {"id":955,"first_name":"Ursala","last_name":"Oller","email":"uollerqi@jigsy.com"} 956 | {"id":956,"first_name":"Emlynn","last_name":"Girardin","email":"egirardinqj@zdnet.com"} 957 | {"id":957,"first_name":"Jarid","last_name":"Fargie","email":"jfargieqk@chicagotribune.com"} 958 | {"id":958,"first_name":"Laurens","last_name":"Danihelka","email":"ldanihelkaql@gmpg.org"} 959 | {"id":959,"first_name":"Ignaz","last_name":"Drinan","email":"idrinanqm@cbslocal.com"} 960 | {"id":960,"first_name":"Michaela","last_name":"Benning","email":"mbenningqn@ocn.ne.jp"} 961 | {"id":961,"first_name":"Anita","last_name":"Dericot","email":"adericotqo@ihg.com"} 962 | {"id":962,"first_name":"Giselbert","last_name":"Grene","email":"ggreneqp@arizona.edu"} 963 | {"id":963,"first_name":"Daphne","last_name":"Deny","email":"ddenyqq@google.co.uk"} 964 | {"id":964,"first_name":"Josefa","last_name":"Scoular","email":"jscoularqr@cargocollective.com"} 965 | {"id":965,"first_name":"Papagena","last_name":"Blatcher","email":"pblatcherqs@time.com"} 966 | {"id":966,"first_name":"Symon","last_name":"Fearneley","email":"sfearneleyqt@usgs.gov"} 967 | {"id":967,"first_name":"Flinn","last_name":"Oak","email":"foakqu@wsj.com"} 968 | {"id":968,"first_name":"Aeriela","last_name":"Ofen","email":"aofenqv@about.me"} 969 | {"id":969,"first_name":"Belia","last_name":"Abdee","email":"babdeeqw@lycos.com"} 970 | {"id":970,"first_name":"Dee","last_name":"Sigg","email":"dsiggqx@360.cn"} 971 | {"id":971,"first_name":"Gilberte","last_name":"Kitchin","email":"gkitchinqy@harvard.edu"} 972 | {"id":972,"first_name":"Adelaide","last_name":"Clinch","email":"aclinchqz@opera.com"} 973 | {"id":973,"first_name":"Lemmie","last_name":"Gonnet","email":"lgonnetr0@geocities.com"} 974 | {"id":974,"first_name":"Redd","last_name":"Cham","email":"rchamr1@mtv.com"} 975 | {"id":975,"first_name":"Hester","last_name":"Belton","email":"hbeltonr2@craigslist.org"} 976 | {"id":976,"first_name":"Barry","last_name":"Sharrard","email":"bsharrardr3@mozilla.com"} 977 | {"id":977,"first_name":"Carney","last_name":"Skepper","email":"cskepperr4@vkontakte.ru"} 978 | {"id":978,"first_name":"Karleen","last_name":"Baigent","email":"kbaigentr5@topsy.com"} 979 | {"id":979,"first_name":"Jany","last_name":"Geraghty","email":"jgeraghtyr6@google.com"} 980 | {"id":980,"first_name":"Valdemar","last_name":"Kleinfeld","email":"vkleinfeldr7@github.io"} 981 | {"id":981,"first_name":"Dierdre","last_name":"Sydenham","email":"dsydenhamr8@uiuc.edu"} 982 | {"id":982,"first_name":"Florella","last_name":"Libermore","email":"flibermorer9@europa.eu"} 983 | {"id":983,"first_name":"Stanley","last_name":"Agron","email":"sagronra@census.gov"} 984 | {"id":984,"first_name":"Estel","last_name":"Guerrieri","email":"eguerrierirb@wikispaces.com"} 985 | {"id":985,"first_name":"Leonie","last_name":"Potebury","email":"lpoteburyrc@ebay.co.uk"} 986 | {"id":986,"first_name":"Freeland","last_name":"Caselli","email":"fcasellird@nydailynews.com"} 987 | {"id":987,"first_name":"Sol","last_name":"Skamell","email":"sskamellre@gmpg.org"} 988 | {"id":988,"first_name":"Jakie","last_name":"Portal","email":"jportalrf@freewebs.com"} 989 | {"id":989,"first_name":"Flory","last_name":"Stothart","email":"fstothartrg@google.co.jp"} 990 | {"id":990,"first_name":"Lacy","last_name":"Scotter","email":"lscotterrh@pagesperso-orange.fr"} 991 | {"id":991,"first_name":"Mauricio","last_name":"Adamthwaite","email":"madamthwaiteri@cloudflare.com"} 992 | {"id":992,"first_name":"Bev","last_name":"Whisson","email":"bwhissonrj@de.vu"} 993 | {"id":993,"first_name":"Eryn","last_name":"Dowbakin","email":"edowbakinrk@salon.com"} 994 | {"id":994,"first_name":"Marlo","last_name":"Craxford","email":"mcraxfordrl@aboutads.info"} 995 | {"id":995,"first_name":"Tracy","last_name":"Dougliss","email":"tdouglissrm@php.net"} 996 | {"id":996,"first_name":"Hermann","last_name":"Frantzen","email":"hfrantzenrn@sitemeter.com"} 997 | {"id":997,"first_name":"Vivien","last_name":"Drewery","email":"vdreweryro@imgur.com"} 998 | {"id":998,"first_name":"Papageno","last_name":"Greenstead","email":"pgreensteadrp@seattletimes.com"} 999 | {"id":999,"first_name":"Freeman","last_name":"Laguerre","email":"flaguerrerq@cisco.com"} 1000 | {"id":1000,"first_name":"Cameron","last_name":"Tocque","email":"ctocquerr@newsvine.com"} -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | comment_width = 120 2 | format_strings = true 3 | group_imports = "StdExternalCrate" 4 | imports_granularity = "Module" 5 | normalize_comments = true 6 | where_single_line = true 7 | wrap_comments = true 8 | -------------------------------------------------------------------------------- /src/cowstr.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Cow; 2 | use std::ops::Deref; 3 | 4 | use serde::Deserialize; 5 | 6 | /// A wrapper around `Cow` that implements `Deserialize` and can deserialize 7 | /// string keys into Cow::Borrowed when possible. 8 | /// 9 | /// This is because serde always deserializes strings into `Cow::Owned`. 10 | /// https://github.com/serde-rs/serde/issues/1852#issuecomment-559517427 11 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize)] 12 | pub struct CowStr<'a>(#[serde(borrow)] pub Cow<'a, str>); 13 | 14 | impl Deref for CowStr<'_> { 15 | type Target = str; 16 | 17 | fn deref(&self) -> &Self::Target { 18 | &self.0 19 | } 20 | } 21 | 22 | impl PartialEq<&str> for CowStr<'_> { 23 | fn eq(&self, other: &&str) -> bool { 24 | self.0 == *other 25 | } 26 | } 27 | 28 | impl<'a> From<&'a str> for CowStr<'a> { 29 | fn from(s: &'a str) -> Self { 30 | Self(Cow::Borrowed(s)) 31 | } 32 | } 33 | 34 | impl<'a> From> for Cow<'a, str> { 35 | fn from(s: CowStr<'a>) -> Self { 36 | s.0 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/de.rs: -------------------------------------------------------------------------------- 1 | // use crate::error::Error; 2 | use core::fmt; 3 | use std::borrow::Cow; 4 | 5 | use serde::de::{Deserialize, MapAccess, SeqAccess, Visitor}; 6 | 7 | use crate::object_vec::ObjectAsVec; 8 | use crate::value::Value; 9 | 10 | impl<'de> Deserialize<'de> for Value<'de> { 11 | #[inline] 12 | fn deserialize(deserializer: D) -> Result, D::Error> 13 | where D: serde::Deserializer<'de> { 14 | struct ValueVisitor; 15 | 16 | impl<'de> Visitor<'de> for ValueVisitor { 17 | type Value = Value<'de>; 18 | 19 | fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 20 | formatter.write_str("any valid JSON value") 21 | } 22 | 23 | #[inline] 24 | fn visit_bool(self, value: bool) -> Result, E> { 25 | Ok(Value::Bool(value)) 26 | } 27 | 28 | #[inline] 29 | fn visit_i64(self, value: i64) -> Result, E> { 30 | Ok(Value::Number(value.into())) 31 | } 32 | 33 | #[inline] 34 | fn visit_u64(self, value: u64) -> Result, E> { 35 | Ok(Value::Number(value.into())) 36 | } 37 | 38 | #[inline] 39 | fn visit_f64(self, value: f64) -> Result, E> { 40 | Ok(Value::Number(value.into())) 41 | } 42 | 43 | #[inline] 44 | fn visit_string(self, v: String) -> Result 45 | where E: serde::de::Error { 46 | Ok(Value::Str(v.into())) 47 | } 48 | 49 | #[inline] 50 | fn visit_str(self, v: &str) -> Result 51 | where E: serde::de::Error { 52 | Ok(Value::Str(Cow::Owned(v.to_owned()))) 53 | } 54 | 55 | #[inline] 56 | fn visit_borrowed_str(self, v: &'de str) -> Result 57 | where E: serde::de::Error { 58 | Ok(Value::Str(Cow::Borrowed(v))) 59 | } 60 | 61 | #[inline] 62 | fn visit_none(self) -> Result, E> { 63 | Ok(Value::Null) 64 | } 65 | 66 | #[inline] 67 | fn visit_i8(self, v: i8) -> Result { 68 | Ok(Value::Number((v as i64).into())) 69 | } 70 | 71 | #[inline] 72 | fn visit_i16(self, v: i16) -> Result { 73 | Ok(Value::Number((v as i64).into())) 74 | } 75 | 76 | #[inline] 77 | fn visit_i32(self, v: i32) -> Result { 78 | Ok(Value::Number((v as i64).into())) 79 | } 80 | 81 | #[inline] 82 | fn visit_u8(self, v: u8) -> Result { 83 | Ok(Value::Number((v as u64).into())) 84 | } 85 | 86 | #[inline] 87 | fn visit_u16(self, v: u16) -> Result { 88 | Ok(Value::Number((v as u64).into())) 89 | } 90 | 91 | #[inline] 92 | fn visit_u32(self, v: u32) -> Result { 93 | Ok(Value::Number((v as u64).into())) 94 | } 95 | 96 | #[inline] 97 | fn visit_f32(self, v: f32) -> Result { 98 | Ok(Value::Number((v as f64).into())) 99 | } 100 | 101 | #[inline] 102 | fn visit_some(self, deserializer: D) -> Result, D::Error> 103 | where D: serde::Deserializer<'de> { 104 | Deserialize::deserialize(deserializer) 105 | } 106 | 107 | #[inline] 108 | fn visit_unit(self) -> Result, E> { 109 | Ok(Value::Null) 110 | } 111 | 112 | #[inline] 113 | fn visit_seq(self, mut visitor: V) -> Result, V::Error> 114 | where V: SeqAccess<'de> { 115 | let mut vec = Vec::with_capacity(visitor.size_hint().unwrap_or(0)); 116 | 117 | while let Some(elem) = visitor.next_element()? { 118 | vec.push(elem); 119 | } 120 | 121 | Ok(Value::Array(vec)) 122 | } 123 | 124 | #[inline] 125 | fn visit_map(self, mut visitor: V) -> Result, V::Error> 126 | where V: MapAccess<'de> { 127 | let mut values = Vec::with_capacity(visitor.size_hint().unwrap_or(0)); 128 | 129 | while let Some((key, value)) = visitor.next_entry()? { 130 | values.push((key, value)); 131 | } 132 | 133 | Ok(Value::Object(ObjectAsVec(values))) 134 | } 135 | } 136 | 137 | deserializer.deserialize_any(ValueVisitor) 138 | } 139 | } 140 | 141 | #[cfg(test)] 142 | mod tests { 143 | 144 | use std::borrow::Cow; 145 | 146 | use crate::Value; 147 | 148 | #[cfg(feature = "cowkeys")] 149 | #[test] 150 | fn cowkeys() { 151 | let json_obj = r#" 152 | { 153 | "bool": true, 154 | "escaped\"": true 155 | } 156 | "#; 157 | 158 | let val: Value = serde_json::from_str(json_obj).unwrap(); 159 | 160 | let obj = val.as_object().unwrap(); 161 | assert!(matches!(obj.as_vec()[0].0.clone().into(), Cow::Borrowed(_))); 162 | assert!(matches!(obj.as_vec()[1].0.clone().into(), Cow::Owned(_))); 163 | } 164 | 165 | #[test] 166 | fn deserialize_json_test() { 167 | let json_obj = r#" 168 | { 169 | "bool": true, 170 | "string_key": "string_val", 171 | "float": 1.23, 172 | "i64": -123, 173 | "u64": 123 174 | } 175 | "#; 176 | 177 | let val: Value = serde_json::from_str(json_obj).unwrap(); 178 | assert_eq!(val.get("bool"), &Value::Bool(true)); 179 | assert_eq!( 180 | val.get("string_key"), 181 | &Value::Str(Cow::Borrowed("string_val")) 182 | ); 183 | assert_eq!(val.get("float"), &Value::Number(1.23.into())); 184 | assert_eq!(val.get("i64"), &Value::Number((-123i64).into())); 185 | assert_eq!(val.get("u64"), &Value::Number(123u64.into())); 186 | } 187 | 188 | #[test] 189 | fn deserialize_json_allow_escaped_strings_in_values() { 190 | let json_obj = r#" 191 | { 192 | "bool": true, 193 | "string_key": "string\"_val", 194 | "u64": 123 195 | } 196 | "#; 197 | 198 | let val: Value = serde_json::from_str(json_obj).unwrap(); 199 | assert_eq!(val.get("bool"), &Value::Bool(true)); 200 | assert_eq!( 201 | val.get("string_key"), 202 | &Value::Str(Cow::Borrowed("string\"_val")) 203 | ); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /src/deserializer.rs: -------------------------------------------------------------------------------- 1 | use serde::de::{self, IntoDeserializer, MapAccess, SeqAccess, Visitor}; 2 | use serde::Deserializer; 3 | 4 | use crate::num::N; 5 | use crate::{KeyStrType, Value}; 6 | 7 | impl<'de> IntoDeserializer<'de, de::value::Error> for &'de Value<'_> { 8 | type Deserializer = Self; 9 | 10 | fn into_deserializer(self) -> Self::Deserializer { 11 | self 12 | } 13 | } 14 | 15 | impl<'de> Deserializer<'de> for &'de Value<'_> { 16 | type Error = de::value::Error; 17 | 18 | fn deserialize_any(self, visitor: V) -> Result 19 | where V: Visitor<'de> { 20 | match self { 21 | Value::Null => visitor.visit_unit(), 22 | Value::Bool(b) => visitor.visit_bool(*b), 23 | Value::Number(n) => match n.n { 24 | N::PosInt(u) => visitor.visit_u64(u), 25 | N::NegInt(i) => visitor.visit_i64(i), 26 | N::Float(f) => visitor.visit_f64(f), 27 | }, 28 | Value::Str(s) => visitor.visit_borrowed_str(s), 29 | Value::Array(arr) => { 30 | let seq = SeqDeserializer::new(arr); 31 | visitor.visit_seq(seq) 32 | } 33 | Value::Object(map) => { 34 | let map = MapDeserializer::new(map.as_vec().as_slice()); 35 | visitor.visit_map(map) 36 | } 37 | } 38 | } 39 | 40 | fn deserialize_bool(self, visitor: V) -> Result 41 | where V: Visitor<'de> { 42 | self.deserialize_any(visitor) 43 | } 44 | 45 | fn deserialize_i8(self, visitor: V) -> Result 46 | where V: Visitor<'de> { 47 | self.deserialize_any(visitor) 48 | } 49 | 50 | fn deserialize_i16(self, visitor: V) -> Result 51 | where V: Visitor<'de> { 52 | self.deserialize_any(visitor) 53 | } 54 | 55 | fn deserialize_i32(self, visitor: V) -> Result 56 | where V: Visitor<'de> { 57 | self.deserialize_any(visitor) 58 | } 59 | 60 | fn deserialize_i64(self, visitor: V) -> Result 61 | where V: Visitor<'de> { 62 | self.deserialize_any(visitor) 63 | } 64 | 65 | fn deserialize_u8(self, visitor: V) -> Result 66 | where V: Visitor<'de> { 67 | self.deserialize_any(visitor) 68 | } 69 | 70 | fn deserialize_u16(self, visitor: V) -> Result 71 | where V: Visitor<'de> { 72 | self.deserialize_any(visitor) 73 | } 74 | 75 | fn deserialize_u32(self, visitor: V) -> Result 76 | where V: Visitor<'de> { 77 | self.deserialize_any(visitor) 78 | } 79 | 80 | fn deserialize_u64(self, visitor: V) -> Result 81 | where V: Visitor<'de> { 82 | self.deserialize_any(visitor) 83 | } 84 | 85 | fn deserialize_f32(self, visitor: V) -> Result 86 | where V: Visitor<'de> { 87 | self.deserialize_any(visitor) 88 | } 89 | 90 | fn deserialize_f64(self, visitor: V) -> Result 91 | where V: Visitor<'de> { 92 | self.deserialize_any(visitor) 93 | } 94 | 95 | fn deserialize_char(self, visitor: V) -> Result 96 | where V: Visitor<'de> { 97 | self.deserialize_any(visitor) 98 | } 99 | 100 | fn deserialize_str(self, visitor: V) -> Result 101 | where V: Visitor<'de> { 102 | self.deserialize_any(visitor) 103 | } 104 | 105 | fn deserialize_string(self, visitor: V) -> Result 106 | where V: Visitor<'de> { 107 | self.deserialize_any(visitor) 108 | } 109 | 110 | fn deserialize_bytes(self, visitor: V) -> Result 111 | where V: Visitor<'de> { 112 | self.deserialize_byte_buf(visitor) 113 | } 114 | 115 | fn deserialize_byte_buf(self, visitor: V) -> Result 116 | where V: Visitor<'de> { 117 | self.deserialize_any(visitor) 118 | } 119 | 120 | fn deserialize_option(self, visitor: V) -> Result 121 | where V: Visitor<'de> { 122 | match self { 123 | Value::Null => visitor.visit_none(), 124 | _ => visitor.visit_some(self), 125 | } 126 | } 127 | 128 | fn deserialize_unit(self, visitor: V) -> Result 129 | where V: Visitor<'de> { 130 | self.deserialize_any(visitor) 131 | } 132 | 133 | fn deserialize_newtype_struct( 134 | self, 135 | _name: &'static str, 136 | visitor: V, 137 | ) -> Result 138 | where 139 | V: Visitor<'de>, 140 | { 141 | visitor.visit_newtype_struct(self) 142 | } 143 | 144 | fn deserialize_seq(self, visitor: V) -> Result 145 | where V: Visitor<'de> { 146 | self.deserialize_any(visitor) 147 | } 148 | 149 | fn deserialize_tuple(self, _len: usize, visitor: V) -> Result 150 | where V: Visitor<'de> { 151 | self.deserialize_seq(visitor) 152 | } 153 | 154 | fn deserialize_tuple_struct( 155 | self, 156 | _name: &'static str, 157 | _len: usize, 158 | visitor: V, 159 | ) -> Result 160 | where 161 | V: Visitor<'de>, 162 | { 163 | self.deserialize_seq(visitor) 164 | } 165 | 166 | fn deserialize_map(self, visitor: V) -> Result 167 | where V: Visitor<'de> { 168 | self.deserialize_any(visitor) 169 | } 170 | 171 | fn deserialize_enum( 172 | self, 173 | _name: &'static str, 174 | _variants: &'static [&'static str], 175 | _visitor: V, 176 | ) -> Result 177 | where 178 | V: Visitor<'de>, 179 | { 180 | Err(de::Error::custom("deserialize_enum is not yet supported")) 181 | } 182 | 183 | fn deserialize_identifier(self, visitor: V) -> Result 184 | where V: Visitor<'de> { 185 | self.deserialize_string(visitor) 186 | } 187 | 188 | fn deserialize_ignored_any(self, visitor: V) -> Result 189 | where V: Visitor<'de> { 190 | visitor.visit_unit() 191 | } 192 | 193 | fn deserialize_unit_struct( 194 | self, 195 | _name: &'static str, 196 | visitor: V, 197 | ) -> Result 198 | where 199 | V: Visitor<'de>, 200 | { 201 | self.deserialize_unit(visitor) 202 | } 203 | 204 | fn deserialize_struct( 205 | self, 206 | _name: &'static str, 207 | _fields: &'static [&'static str], 208 | visitor: V, 209 | ) -> Result 210 | where 211 | V: Visitor<'de>, 212 | { 213 | self.deserialize_any(visitor) 214 | } 215 | } 216 | 217 | // Helper struct to deserialize sequences (arrays). 218 | struct SeqDeserializer<'a, 'ctx> { 219 | iter: std::slice::Iter<'a, Value<'ctx>>, 220 | } 221 | 222 | impl<'a, 'ctx> SeqDeserializer<'a, 'ctx> { 223 | fn new(slice: &'a [Value<'ctx>]) -> Self { 224 | SeqDeserializer { iter: slice.iter() } 225 | } 226 | } 227 | 228 | impl<'de, 'a: 'de, 'ctx: 'de> SeqAccess<'de> for SeqDeserializer<'a, 'ctx> { 229 | type Error = de::value::Error; 230 | 231 | fn next_element_seed(&mut self, seed: T) -> Result, Self::Error> 232 | where T: de::DeserializeSeed<'de> { 233 | self.iter 234 | .next() 235 | .map(|value| seed.deserialize(value)) 236 | .transpose() 237 | } 238 | } 239 | 240 | // Helper struct to deserialize maps (objects). 241 | struct MapDeserializer<'a, 'ctx> { 242 | iter: std::slice::Iter<'a, (KeyStrType<'ctx>, Value<'ctx>)>, 243 | value: Option<&'a Value<'ctx>>, 244 | } 245 | 246 | impl<'a, 'ctx> MapDeserializer<'a, 'ctx> { 247 | fn new(map: &'a [(KeyStrType<'ctx>, Value<'ctx>)]) -> Self { 248 | MapDeserializer { 249 | iter: map.iter(), 250 | value: None, 251 | } 252 | } 253 | } 254 | 255 | impl<'de, 'a: 'de, 'ctx: 'de> MapAccess<'de> for MapDeserializer<'a, 'ctx> { 256 | type Error = de::value::Error; 257 | 258 | fn next_key_seed(&mut self, seed: K) -> Result, Self::Error> 259 | where K: de::DeserializeSeed<'de> { 260 | if let Some((key, value)) = self.iter.next() { 261 | self.value = Some(value); 262 | seed.deserialize(de::value::BorrowedStrDeserializer::new(key)) 263 | .map(Some) 264 | } else { 265 | Ok(None) 266 | } 267 | } 268 | 269 | fn next_value_seed(&mut self, seed: V) -> Result 270 | where V: de::DeserializeSeed<'de> { 271 | match self.value.take() { 272 | Some(value) => seed.deserialize(value), 273 | None => Err(de::Error::custom("value is missing")), 274 | } 275 | } 276 | } 277 | 278 | #[cfg(test)] 279 | mod tests { 280 | use serde::de::value::Error as DeError; 281 | use serde::de::{IgnoredAny, IntoDeserializer}; 282 | use serde::Deserialize; 283 | 284 | use crate::num::N; 285 | use crate::Value; 286 | 287 | // Basic deserialization test for null value 288 | #[test] 289 | fn test_deserialize_null() { 290 | let value = Value::Null; 291 | let deserialized: Option = Deserialize::deserialize(&value).unwrap(); 292 | assert_eq!(deserialized, None); 293 | } 294 | 295 | // Test deserialization of boolean value 296 | #[test] 297 | fn test_deserialize_bool() { 298 | let value = Value::Bool(true); 299 | let deserialized: bool = Deserialize::deserialize(&value).unwrap(); 300 | assert!(deserialized); 301 | } 302 | 303 | #[test] 304 | fn test_into_deserializer_bool() { 305 | let value = Value::Bool(true); 306 | 307 | // Convert Value to deserializer using IntoDeserializer 308 | let deserializer = (&value).into_deserializer(); 309 | let deserialized: bool = Deserialize::deserialize(deserializer).unwrap(); 310 | 311 | assert!(deserialized); 312 | } 313 | 314 | // Test deserialization of integer (i64) value 315 | #[test] 316 | fn test_deserialize_i64() { 317 | let value = Value::Number(N::NegInt(-42).into()); 318 | let deserialized: i64 = Deserialize::deserialize(&value).unwrap(); 319 | assert_eq!(deserialized, -42); 320 | } 321 | 322 | // Test deserialization of unsigned integer (u64) value 323 | #[test] 324 | fn test_deserialize_u64() { 325 | let value = Value::Number(N::PosInt(42).into()); 326 | let deserialized: u64 = Deserialize::deserialize(&value).unwrap(); 327 | assert_eq!(deserialized, 42); 328 | } 329 | 330 | // Test deserialization of floating point (f64) value 331 | #[test] 332 | fn test_deserialize_f64() { 333 | let value = Value::Number(N::Float(42.5).into()); 334 | let deserialized: f64 = Deserialize::deserialize(&value).unwrap(); 335 | assert_eq!(deserialized, 42.5); 336 | } 337 | 338 | // Test deserialization of string value 339 | #[test] 340 | fn test_deserialize_str() { 341 | let value = Value::Str("Hello".into()); 342 | let deserialized: String = Deserialize::deserialize(&value).unwrap(); 343 | assert_eq!(deserialized, "Hello"); 344 | } 345 | 346 | // Test deserialization of optional value when null 347 | #[test] 348 | fn test_deserialize_option_none() { 349 | let value = Value::Null; 350 | let deserialized: Option = Deserialize::deserialize(&value).unwrap(); 351 | assert_eq!(deserialized, None); 352 | } 353 | 354 | // Test deserialization of optional value when present 355 | #[test] 356 | fn test_deserialize_option_some() { 357 | let value = Value::Number(N::PosInt(42).into()); 358 | let deserialized: Option = Deserialize::deserialize(&value).unwrap(); 359 | assert_eq!(deserialized, Some(42)); 360 | } 361 | 362 | // Test deserialization of an array (sequence of values) 363 | #[test] 364 | fn test_deserialize_array() { 365 | let value = Value::Array(vec![ 366 | Value::Number(N::PosInt(1).into()), 367 | Value::Number(N::PosInt(2).into()), 368 | Value::Number(N::PosInt(3).into()), 369 | ]); 370 | 371 | let deserialized: Vec = Deserialize::deserialize(&value).unwrap(); 372 | assert_eq!(deserialized, vec![1, 2, 3]); 373 | } 374 | 375 | // Test deserialization of a map (object) 376 | #[test] 377 | fn test_deserialize_map() { 378 | let value = Value::Object( 379 | vec![ 380 | ("key1", Value::Number(N::PosInt(1).into())), 381 | ("key2", Value::Number(N::PosInt(2).into())), 382 | ("key3", Value::Number(N::PosInt(3).into())), 383 | ] 384 | .into(), 385 | ); 386 | 387 | let deserialized: std::collections::HashMap = 388 | Deserialize::deserialize(&value).unwrap(); 389 | 390 | let mut expected = std::collections::HashMap::new(); 391 | expected.insert("key1".to_string(), 1); 392 | expected.insert("key2".to_string(), 2); 393 | expected.insert("key3".to_string(), 3); 394 | 395 | assert_eq!(deserialized, expected); 396 | } 397 | 398 | // Test deserialization of a tuple 399 | #[test] 400 | fn test_deserialize_tuple() { 401 | let value = Value::Array(vec![ 402 | Value::Number(N::PosInt(1).into()), 403 | Value::Str("Hello".into()), 404 | ]); 405 | 406 | let deserialized: (u64, String) = Deserialize::deserialize(&value).unwrap(); 407 | assert_eq!(deserialized, (1, "Hello".to_string())); 408 | } 409 | 410 | // Test deserialization of a nested structure (array within an object) 411 | #[test] 412 | fn test_deserialize_nested() { 413 | let value = Value::Object( 414 | vec![( 415 | "numbers", 416 | Value::Array(vec![ 417 | Value::Number(N::PosInt(1).into()), 418 | Value::Number(N::PosInt(2).into()), 419 | Value::Number(N::PosInt(3).into()), 420 | ]), 421 | )] 422 | .into(), 423 | ); 424 | 425 | #[derive(Deserialize, Debug, PartialEq)] 426 | struct Nested { 427 | numbers: Vec, 428 | } 429 | 430 | let deserialized: Nested = Deserialize::deserialize(&value).unwrap(); 431 | assert_eq!( 432 | deserialized, 433 | Nested { 434 | numbers: vec![1, 2, 3] 435 | } 436 | ); 437 | } 438 | 439 | // Test deserialization of a newtype struct 440 | #[derive(Debug, Deserialize, PartialEq)] 441 | struct NewtypeStruct(u64); 442 | 443 | #[test] 444 | fn test_deserialize_newtype_struct() { 445 | let value = Value::Number(N::PosInt(42).into()); 446 | let deserialized: NewtypeStruct = Deserialize::deserialize(&value).unwrap(); 447 | assert_eq!(deserialized, NewtypeStruct(42)); 448 | } 449 | 450 | #[test] 451 | fn test_deserialize_ignored_any_with_string() { 452 | let value = Value::Str("Ignored".into()); 453 | 454 | let _deserialized: IgnoredAny = Deserialize::deserialize(&value).unwrap(); 455 | } 456 | 457 | // Test deserialization failure (for an unsupported type like enum) 458 | #[test] 459 | fn test_deserialize_enum_fails() { 460 | let value = Value::Str("EnumVariant".into()); 461 | let result: Result<(), DeError> = Deserialize::deserialize(&value); 462 | assert!(result.is_err()); 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /src/index.rs: -------------------------------------------------------------------------------- 1 | use super::Value; 2 | 3 | /// A type that can be used to index into a `serde_json_borrow::Value`. 4 | /// 5 | /// [`get`] of `Value` accept any type that implements `Index`. This 6 | /// trait is implemented for strings which are used as the index into a JSON 7 | /// map, and for `usize` which is used as the index into a JSON array. 8 | /// 9 | /// [`get`]: ../enum.Value.html#method.get 10 | /// 11 | /// This trait is sealed and cannot be implemented for types outside of 12 | /// `serde_json_borrow`. 13 | /// # Examples 14 | /// 15 | /// ``` 16 | /// # use serde_json_borrow::Value; 17 | /// # 18 | /// let json_obj = r#" 19 | /// { 20 | /// "x": { 21 | /// "y": ["z", "zz"] 22 | /// } 23 | /// } 24 | /// "#; 25 | /// 26 | /// let data: Value = serde_json::from_str(json_obj).unwrap(); 27 | /// 28 | /// assert_eq!(data.get("x").get("y").get(0), &Value::Str(std::borrow::Cow::Borrowed("z"))); 29 | /// assert_eq!(data.get("x").get("y").get(1), &Value::Str(std::borrow::Cow::Borrowed("zz"))); 30 | /// assert_eq!(data.get("x").get("y").get(2), &Value::Null); 31 | /// 32 | /// assert_eq!(data.get("a"), &Value::Null); 33 | /// assert_eq!(data.get("a").get("b"), &Value::Null); 34 | /// ``` 35 | pub trait Index<'v> { 36 | /// Return None if the key is not already in the array or object. 37 | #[doc(hidden)] 38 | fn index_into(self, v: &'v Value<'v>) -> Option<&'v Value<'v>>; 39 | } 40 | 41 | impl<'v> Index<'v> for usize { 42 | #[inline] 43 | fn index_into(self, v: &'v Value<'v>) -> Option<&'v Value<'v>> { 44 | match v { 45 | Value::Array(vec) => vec.get(self), 46 | _ => None, 47 | } 48 | } 49 | } 50 | 51 | impl<'v, 'a: 'v> Index<'v> for &'a str { 52 | #[inline] 53 | fn index_into(self, v: &'v Value<'v>) -> Option<&'v Value<'v>> { 54 | match v { 55 | Value::Object(map) => map.iter().find(|(k, _v)| k == &self).map(|(_k, v)| v), 56 | _ => None, 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![deny( 2 | missing_copy_implementations, 3 | trivial_casts, 4 | trivial_numeric_casts, 5 | unused_import_braces, 6 | unused_imports, 7 | unused_qualifications, 8 | missing_docs 9 | )] 10 | 11 | //! # Serde JSON Borrowed 12 | //! 13 | //! Parses JSON into [`serde_json_borrow::Value<'ctx>`](Value) from `&'ctx str`. 14 | //! 15 | //! The default [serde_json](https://github.com/serde-rs/json) parses into an owned `serde_json::Value`. 16 | //! In cases where the DOM representation is just an intermediate struct, parsing into owned 17 | //! `serde_json::Value` can cause a lot of overhead. [`serde_json_borrow::Value<'ctx>`](Value) 18 | //! borrows the `Strings` instead. 19 | //! 20 | //! Additionally it pushes the (key,value) for JSON objects into a `Vec` instead of putting the 21 | //! values into a `BTreeMap`. Access works via `ObjectAsVec`, which provides the same API 22 | //! as `BTreeMap`. 23 | //! 24 | //! The primary benefit of using `serde_json_borrow` is a higher JSON _deserialization performance_ 25 | //! due to less allocations. By borrowing a DOM, the library ensures that no additional memory is 26 | //! allocated for `Strings`, that contain no JSON escape codes. 27 | //! 28 | //! ## OwnedValue 29 | //! You can take advantage of [`OwnedValue`] to parse a `String` containing 30 | //! unparsed `JSON` into a `Value` without having to worry about lifetimes, 31 | //! as [`OwnedValue`] will take ownership of the `String` and reference slices of 32 | //! it, rather than making copies. 33 | //! 34 | //! # Limitations 35 | //! The feature flag `cowkeys` uses `Cow` instead of `&str` as keys in objects. This enables 36 | //! support for escaped data in keys. Without the `cowkeys` feature flag `&str` is used, which does 37 | //! not allow any JSON escaping characters in keys. 38 | //! 39 | //! List of _unsupported_ characters (https://www.json.org/json-en.html) in object keys without `cowkeys` feature flag. 40 | //! 41 | //! ```text 42 | //! \" represents the quotation mark character (U+0022). 43 | //! \\ represents the reverse solidus character (U+005C). 44 | //! \/ represents the solidus character (U+002F). 45 | //! \b represents the backspace character (U+0008). 46 | //! \f represents the form feed character (U+000C). 47 | //! \n represents the line feed character (U+000A). 48 | //! \r represents the carriage return character (U+000D). 49 | //! \t represents the character tabulation character (U+0009). 50 | //! ``` 51 | //! # Usage 52 | //! ```rust 53 | //! use std::io; 54 | //! use serde_json_borrow::Value; 55 | //! fn main() -> io::Result<()> { 56 | //! let data = r#"{"bool": true, "key": "123"}"#; 57 | //! let value: Value = serde_json::from_str(&data)?; 58 | //! assert_eq!(value.get("bool"), &Value::Bool(true)); 59 | //! assert_eq!(value.get("key"), &Value::Str("123".into())); 60 | //! Ok(()) 61 | //! } 62 | //! ``` 63 | //! # Performance 64 | //! Performance gain depends on how many allocations can be avoided, and how many objects there are, 65 | //! as deserializing into a vec is significantly faster. 66 | //! 67 | //! The [benchmarks](https://github.com/pseitz/serde_json_borrow#benchmark) in the github repository show around **`1.8x`** speedup, although they don't account 68 | //! for that in practice it won't be a simple consecutive alloc json, dealloc json. There will be 69 | //! other allocations in between. 70 | //! 71 | //! On a hadoop file system log data set benchmark, I get _714Mb/s_ JSON deserialization throughput 72 | //! on my machine. 73 | 74 | mod de; 75 | mod deserializer; 76 | mod index; 77 | mod num; 78 | mod object_vec; 79 | mod owned; 80 | mod ser; 81 | mod value; 82 | 83 | #[cfg(feature = "cowkeys")] 84 | mod cowstr; 85 | 86 | pub use object_vec::{KeyStrType, ObjectAsVec, ObjectAsVec as Map}; 87 | pub use owned::OwnedValue; 88 | pub use value::Value; 89 | -------------------------------------------------------------------------------- /src/num.rs: -------------------------------------------------------------------------------- 1 | use core::hash::{Hash, Hasher}; 2 | 3 | /// Represents a JSON number, whether integer or floating point. 4 | #[derive(Clone, Copy, PartialEq, Eq, Hash)] 5 | pub struct Number { 6 | pub(crate) n: N, 7 | } 8 | 9 | impl From for Number { 10 | fn from(n: N) -> Self { 11 | Self { n } 12 | } 13 | } 14 | 15 | #[derive(Copy, Clone)] 16 | pub(crate) enum N { 17 | PosInt(u64), 18 | /// Always less than zero. 19 | NegInt(i64), 20 | /// Always finite. 21 | Float(f64), 22 | } 23 | 24 | impl Number { 25 | /// If the `Number` is an integer, represent it as i64 if possible. Returns 26 | /// None otherwise. 27 | pub fn as_u64(&self) -> Option { 28 | match self.n { 29 | N::PosInt(v) => Some(v), 30 | _ => None, 31 | } 32 | } 33 | /// If the `Number` is an integer, represent it as u64 if possible. Returns 34 | /// None otherwise. 35 | pub fn as_i64(&self) -> Option { 36 | match self.n { 37 | N::PosInt(n) => { 38 | if n <= i64::MAX as u64 { 39 | Some(n as i64) 40 | } else { 41 | None 42 | } 43 | } 44 | N::NegInt(v) => Some(v), 45 | _ => None, 46 | } 47 | } 48 | 49 | /// Represents the number as f64 if possible. Returns None otherwise. 50 | pub fn as_f64(&self) -> Option { 51 | match self.n { 52 | N::PosInt(n) => Some(n as f64), 53 | N::NegInt(n) => Some(n as f64), 54 | N::Float(n) => Some(n), 55 | } 56 | } 57 | 58 | /// Returns true if the `Number` is a f64. 59 | pub fn is_f64(&self) -> bool { 60 | matches!(self.n, N::Float(_)) 61 | } 62 | 63 | /// Returns true if the `Number` is a u64. 64 | pub fn is_u64(&self) -> bool { 65 | matches!(self.n, N::PosInt(_)) 66 | } 67 | 68 | /// Returns true if the `Number` is an integer between `i64::MIN` and 69 | /// `i64::MAX`. 70 | pub fn is_i64(&self) -> bool { 71 | match self.n { 72 | N::PosInt(v) => v <= i64::MAX as u64, 73 | N::NegInt(_) => true, 74 | N::Float(_) => false, 75 | } 76 | } 77 | } 78 | 79 | impl PartialEq for N { 80 | fn eq(&self, other: &Self) -> bool { 81 | match (self, other) { 82 | (N::PosInt(a), N::PosInt(b)) => a == b, 83 | (N::NegInt(a), N::NegInt(b)) => a == b, 84 | (N::Float(a), N::Float(b)) => a == b, 85 | _ => false, 86 | } 87 | } 88 | } 89 | 90 | // Implementing Eq is fine since any float values are always finite. 91 | impl Eq for N {} 92 | 93 | impl Hash for N { 94 | fn hash(&self, h: &mut H) { 95 | match *self { 96 | N::PosInt(i) => i.hash(h), 97 | N::NegInt(i) => i.hash(h), 98 | N::Float(f) => { 99 | if f == 0.0f64 { 100 | // There are 2 zero representations, +0 and -0, which 101 | // compare equal but have different bits. We use the +0 hash 102 | // for both so that hash(+0) == hash(-0). 103 | 0.0f64.to_bits().hash(h); 104 | } else { 105 | f.to_bits().hash(h); 106 | } 107 | } 108 | } 109 | } 110 | } 111 | impl From for Number { 112 | fn from(val: u64) -> Self { 113 | Self { n: N::PosInt(val) } 114 | } 115 | } 116 | 117 | impl From for Number { 118 | fn from(val: i64) -> Self { 119 | Self { n: N::NegInt(val) } 120 | } 121 | } 122 | 123 | impl From for Number { 124 | fn from(val: f64) -> Self { 125 | Self { n: N::Float(val) } 126 | } 127 | } 128 | 129 | impl From for serde_json::value::Number { 130 | fn from(num: Number) -> Self { 131 | match num.n { 132 | N::PosInt(n) => n.into(), 133 | N::NegInt(n) => n.into(), 134 | N::Float(n) => serde_json::value::Number::from_f64(n).unwrap(), 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/object_vec.rs: -------------------------------------------------------------------------------- 1 | #![allow(clippy::useless_conversion)] 2 | #![allow(clippy::useless_asref)] 3 | 4 | use std::borrow::Cow; 5 | 6 | use crate::Value; 7 | 8 | #[cfg(feature = "cowkeys")] 9 | /// The string type used. Can be toggled between &str and Cow via `cowstr` feature flag 10 | pub type KeyStrType<'a> = crate::cowstr::CowStr<'a>; 11 | 12 | #[cfg(not(feature = "cowkeys"))] 13 | /// The string type used. Can be toggled between &str and Cow via `cowstr` feature flag 14 | /// Cow strings 15 | pub type KeyStrType<'a> = &'a str; 16 | 17 | /// Represents a JSON key/value type. 18 | /// 19 | /// For performance reasons we use a Vec instead of a Hashmap. 20 | /// This comes with a tradeoff of slower key accesses as we need to iterate and compare. 21 | /// 22 | /// The ObjectAsVec struct is a wrapper around a Vec of (&str, Value) pairs. 23 | /// It provides methods to make it easy to migrate from serde_json::Value::Object or 24 | /// serde_json::Map. 25 | #[derive(Debug, Default, Clone, PartialEq, Eq, Hash)] 26 | pub struct ObjectAsVec<'ctx>(pub(crate) Vec<(KeyStrType<'ctx>, Value<'ctx>)>); 27 | 28 | #[cfg(feature = "cowkeys")] 29 | impl<'ctx> From)>> for ObjectAsVec<'ctx> { 30 | fn from(vec: Vec<(&'ctx str, Value<'ctx>)>) -> Self { 31 | Self::from_iter(vec) 32 | } 33 | } 34 | 35 | #[cfg(not(feature = "cowkeys"))] 36 | impl<'ctx> From)>> for ObjectAsVec<'ctx> { 37 | fn from(vec: Vec<(&'ctx str, Value<'ctx>)>) -> Self { 38 | Self(vec) 39 | } 40 | } 41 | 42 | impl<'ctx> FromIterator<(&'ctx str, Value<'ctx>)> for ObjectAsVec<'ctx> { 43 | fn from_iter)>>(iter: T) -> Self { 44 | Self(iter.into_iter().map(|(k, v)| (k.into(), v)).collect()) 45 | } 46 | } 47 | 48 | impl<'ctx> ObjectAsVec<'ctx> { 49 | /// Access to the underlying Vec. 50 | /// 51 | /// # Note 52 | /// Since KeyStrType can be changed via a feature flag avoid using `as_vec` and use other 53 | /// methods instead. This could be a problem with feature unification, when one crate uses it 54 | /// as &str and another uses it as Cow, both will get Cow &Vec<(KeyStrType, Value<'ctx>)> { 57 | &self.0 58 | } 59 | 60 | /// Access to the underlying Vec. Keys are normalized to Cow. 61 | #[inline] 62 | pub fn into_vec(self) -> Vec<(Cow<'ctx, str>, Value<'ctx>)> { 63 | self.0.into_iter().map(|el| (el.0.into(), el.1)).collect() 64 | } 65 | 66 | /// Returns a reference to the value corresponding to the key. 67 | /// 68 | /// ## Performance 69 | /// As this is backed by a Vec, this searches linearly through the Vec as may be much more 70 | /// expensive than a `Hashmap` for larger Objects. 71 | #[inline] 72 | pub fn get(&self, key: &str) -> Option<&Value<'ctx>> { 73 | self.0 74 | .iter() 75 | .find_map(|(k, v)| if *k == key { Some(v) } else { None }) 76 | } 77 | 78 | /// Returns a mutable reference to the value corresponding to the key, if it exists. 79 | /// 80 | /// ## Performance 81 | /// As this is backed by a Vec, this searches linearly through the Vec as may be much more 82 | /// expensive than a `Hashmap` for larger Objects. 83 | #[inline] 84 | pub fn get_mut(&mut self, key: &str) -> Option<&mut Value<'ctx>> { 85 | self.0 86 | .iter_mut() 87 | .find_map(|(k, v)| if *k == key { Some(v) } else { None }) 88 | } 89 | 90 | /// Returns the key-value pair corresponding to the supplied key. 91 | /// 92 | /// ## Performance 93 | /// As this is backed by a Vec, this searches linearly through the Vec as may be much more 94 | /// expensive than a `Hashmap` for larger Objects. 95 | #[inline] 96 | pub fn get_key_value(&self, key: &str) -> Option<(&str, &Value<'ctx>)> { 97 | self.0.iter().find_map(|(k, v)| { 98 | if *k == key { 99 | Some((k.as_ref(), v)) 100 | } else { 101 | None 102 | } 103 | }) 104 | } 105 | 106 | /// An iterator visiting all key-value pairs 107 | #[inline] 108 | pub fn iter(&self) -> impl Iterator)> { 109 | self.0.iter().map(|(k, v)| (k.as_ref(), v)) 110 | } 111 | 112 | /// Returns the number of elements in the object 113 | #[inline] 114 | pub fn len(&self) -> usize { 115 | self.0.len() 116 | } 117 | 118 | /// Returns true if the object contains no elements 119 | #[inline] 120 | pub fn is_empty(&self) -> bool { 121 | self.0.is_empty() 122 | } 123 | 124 | /// An iterator visiting all keys 125 | #[inline] 126 | pub fn keys(&self) -> impl Iterator { 127 | self.0.iter().map(|(k, _)| k.as_ref()) 128 | } 129 | 130 | /// An iterator visiting all values 131 | #[inline] 132 | pub fn values(&self) -> impl Iterator> { 133 | self.0.iter().map(|(_, v)| v) 134 | } 135 | 136 | /// Returns true if the object contains a value for the specified key. 137 | /// 138 | /// ## Performance 139 | /// As this is backed by a Vec, this searches linearly through the Vec as may be much more 140 | /// expensive than a `Hashmap` for larger Objects. 141 | #[inline] 142 | pub fn contains_key(&self, key: &str) -> bool { 143 | self.0.iter().any(|(k, _)| *k == key) 144 | } 145 | 146 | /// Inserts a key-value pair into the object. 147 | /// If the object did not have this key present, `None` is returned. 148 | /// If the object did have this key present, the value is updated, and the old value is 149 | /// returned. 150 | /// 151 | /// ## Performance 152 | /// This operation is linear in the size of the Vec because it potentially requires iterating 153 | /// through all elements to find a matching key. 154 | #[inline] 155 | pub fn insert(&mut self, key: &'ctx str, value: Value<'ctx>) -> Option> { 156 | for (k, v) in &mut self.0 { 157 | if *k == key { 158 | return Some(std::mem::replace(v, value)); 159 | } 160 | } 161 | // If the key is not found, push the new key-value pair to the end of the Vec 162 | self.0.push((key.into(), value)); 163 | None 164 | } 165 | 166 | /// Inserts a key-value pair into the object if the key does not yet exist, otherwise returns a 167 | /// mutable reference to the existing value. 168 | /// 169 | /// ## Performance 170 | /// This operation might be linear in the size of the Vec because it requires iterating through 171 | /// all elements to find a matching key, and might add to the end if not found. 172 | #[inline] 173 | pub fn insert_or_get_mut(&mut self, key: &'ctx str, value: Value<'ctx>) -> &mut Value<'ctx> { 174 | // get position to circumvent lifetime issue 175 | if let Some(pos) = self.0.iter_mut().position(|(k, _)| *k == key) { 176 | &mut self.0[pos].1 177 | } else { 178 | self.0.push((key.into(), value)); 179 | &mut self.0.last_mut().unwrap().1 180 | } 181 | } 182 | 183 | /// Inserts a key-value pair into the object and returns the mutable reference of the inserted 184 | /// value. 185 | /// 186 | /// ## Note 187 | /// The key must not exist in the object. If the key already exists, the object will contain 188 | /// multiple keys afterwards. 189 | /// 190 | /// ## Performance 191 | /// This operation is amortized constant time, worst case linear time in the size of the Vec 192 | /// because it potentially requires a reallocation to grow the Vec. 193 | #[inline] 194 | pub fn insert_unchecked_and_get_mut( 195 | &mut self, 196 | key: &'ctx str, 197 | value: Value<'ctx>, 198 | ) -> &mut Value<'ctx> { 199 | self.0.push((key.into(), value)); 200 | let idx = self.0.len() - 1; 201 | &mut self.0[idx].1 202 | } 203 | } 204 | 205 | impl<'ctx> From> for serde_json::Map { 206 | fn from(val: ObjectAsVec<'ctx>) -> Self { 207 | val.iter() 208 | .map(|(key, val)| (key.to_string(), val.into())) 209 | .collect() 210 | } 211 | } 212 | impl<'ctx> From<&ObjectAsVec<'ctx>> for serde_json::Map { 213 | fn from(val: &ObjectAsVec<'ctx>) -> Self { 214 | val.iter() 215 | .map(|(key, val)| (key.to_owned(), val.into())) 216 | .collect() 217 | } 218 | } 219 | 220 | #[cfg(test)] 221 | mod tests { 222 | use std::borrow::Cow; 223 | 224 | use super::*; 225 | use crate::num::Number; 226 | 227 | #[test] 228 | fn test_empty_initialization() { 229 | let obj: ObjectAsVec = ObjectAsVec(Vec::new()); 230 | assert!(obj.is_empty()); 231 | assert_eq!(obj.len(), 0); 232 | } 233 | 234 | #[test] 235 | fn test_initialization_from_vec() { 236 | let obj = ObjectAsVec::from(vec![ 237 | ("a", Value::Number(0u64.into())), 238 | ("b", Value::Number(1u64.into())), 239 | ("c", Value::Number(2u64.into())), 240 | ]); 241 | 242 | assert_eq!(obj.len(), 3); 243 | assert_eq!(obj.get("a"), Some(&Value::Number(0u64.into()))); 244 | assert_eq!(obj.get("b"), Some(&Value::Number(1u64.into()))); 245 | assert_eq!(obj.get("c"), Some(&Value::Number(2u64.into()))); 246 | } 247 | 248 | #[test] 249 | fn test_initialization_from_iter() { 250 | let names = "abcde"; 251 | let iter = (0usize..) 252 | .take(5) 253 | .map(|i| (&names[i..i + 1], Value::Number(Number::from(i as u64)))); 254 | 255 | let obj = ObjectAsVec::from_iter(iter); 256 | 257 | assert_eq!(obj.len(), 5); 258 | assert_eq!(obj.get("a"), Some(&Value::Number(0u64.into()))); 259 | assert_eq!(obj.get("b"), Some(&Value::Number(1u64.into()))); 260 | assert_eq!(obj.get("c"), Some(&Value::Number(2u64.into()))); 261 | assert_eq!(obj.get("d"), Some(&Value::Number(3u64.into()))); 262 | assert_eq!(obj.get("e"), Some(&Value::Number(4u64.into()))); 263 | } 264 | 265 | #[test] 266 | fn test_non_empty_initialization() { 267 | let obj = ObjectAsVec(vec![("key".into(), Value::Null)]); 268 | assert!(!obj.is_empty()); 269 | assert_eq!(obj.len(), 1); 270 | } 271 | 272 | #[test] 273 | fn test_get_existing_key() { 274 | let obj = ObjectAsVec(vec![("key".into(), Value::Bool(true))]); 275 | assert_eq!(obj.get("key"), Some(&Value::Bool(true))); 276 | } 277 | 278 | #[test] 279 | fn test_get_non_existing_key() { 280 | let obj = ObjectAsVec(vec![("key".into(), Value::Bool(true))]); 281 | assert_eq!(obj.get("not_a_key"), None); 282 | } 283 | 284 | #[test] 285 | fn test_get_key_value() { 286 | let obj = ObjectAsVec(vec![("key".into(), Value::Bool(true))]); 287 | assert_eq!(obj.get_key_value("key"), Some(("key", &Value::Bool(true)))); 288 | } 289 | 290 | #[test] 291 | fn test_keys_iterator() { 292 | let obj = ObjectAsVec(vec![ 293 | ("key1".into(), Value::Null), 294 | ("key2".into(), Value::Bool(false)), 295 | ]); 296 | let keys: Vec<_> = obj.keys().collect(); 297 | assert_eq!(keys, vec!["key1", "key2"]); 298 | } 299 | 300 | #[test] 301 | fn test_values_iterator() { 302 | let obj = ObjectAsVec(vec![ 303 | ("key1".into(), Value::Null), 304 | ("key2".into(), Value::Bool(true)), 305 | ]); 306 | let values: Vec<_> = obj.values().collect(); 307 | assert_eq!(values, vec![&Value::Null, &Value::Bool(true)]); 308 | } 309 | 310 | #[test] 311 | fn test_iter() { 312 | let obj = ObjectAsVec(vec![ 313 | ("key1".into(), Value::Null), 314 | ("key2".into(), Value::Bool(true)), 315 | ]); 316 | let pairs: Vec<_> = obj.iter().collect(); 317 | assert_eq!( 318 | pairs, 319 | vec![("key1", &Value::Null), ("key2", &Value::Bool(true))] 320 | ); 321 | } 322 | 323 | #[test] 324 | fn test_into_vec() { 325 | let obj = ObjectAsVec(vec![("key".into(), Value::Null)]); 326 | let vec = obj.into_vec(); 327 | assert_eq!(vec, vec![("key".into(), Value::Null)]); 328 | } 329 | 330 | #[test] 331 | fn test_contains_key() { 332 | let obj = ObjectAsVec(vec![("key".into(), Value::Bool(false))]); 333 | assert!(obj.contains_key("key")); 334 | assert!(!obj.contains_key("no_key")); 335 | } 336 | 337 | #[test] 338 | fn test_insert_new() { 339 | let mut obj = ObjectAsVec::default(); 340 | assert_eq!( 341 | obj.insert("key1", Value::Str(Cow::Borrowed("value1"))), 342 | None 343 | ); 344 | assert_eq!(obj.len(), 1); 345 | assert_eq!(obj.get("key1"), Some(&Value::Str(Cow::Borrowed("value1")))); 346 | } 347 | 348 | #[test] 349 | fn test_insert_update() { 350 | let mut obj = ObjectAsVec(vec![( 351 | "key1".into(), 352 | Value::Str(Cow::Borrowed("old_value1")), 353 | )]); 354 | assert_eq!( 355 | obj.insert("key1", Value::Str(Cow::Borrowed("new_value1"))), 356 | Some(Value::Str(Cow::Borrowed("old_value1"))) 357 | ); 358 | assert_eq!(obj.len(), 1); 359 | assert_eq!( 360 | obj.get("key1"), 361 | Some(&Value::Str(Cow::Borrowed("new_value1"))) 362 | ); 363 | } 364 | 365 | #[test] 366 | fn test_insert_multiple_types() { 367 | let mut obj = ObjectAsVec::default(); 368 | obj.insert("boolean", Value::Bool(true)); 369 | obj.insert("number", Value::Number(3.14.into())); 370 | obj.insert("string", Value::Str(Cow::Borrowed("Hello"))); 371 | obj.insert("null", Value::Null); 372 | 373 | assert_eq!( 374 | obj.insert( 375 | "array", 376 | Value::Array(vec![Value::Number(1_u64.into()), Value::Null]) 377 | ), 378 | None 379 | ); 380 | assert_eq!(obj.len(), 5); 381 | assert_eq!(obj.get("boolean"), Some(&Value::Bool(true))); 382 | assert_eq!(obj.get("number"), Some(&Value::Number(3.14.into()))); 383 | assert_eq!(obj.get("string"), Some(&Value::Str(Cow::Borrowed("Hello")))); 384 | assert_eq!(obj.get("null"), Some(&Value::Null)); 385 | assert_eq!( 386 | obj.get("array"), 387 | Some(&Value::Array(vec![ 388 | Value::Number(1_u64.into()), 389 | Value::Null 390 | ])) 391 | ); 392 | } 393 | } 394 | -------------------------------------------------------------------------------- /src/owned.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::ops::Deref; 3 | 4 | use crate::Value; 5 | 6 | /// Parses a `String` into `Value`, by taking ownership of `String` and reference slices from it in 7 | /// contrast to copying the contents. 8 | /// 9 | /// This is done to mitigate lifetime issues. 10 | #[derive(Clone, Debug, Eq, PartialEq, Hash)] 11 | pub struct OwnedValue { 12 | /// Keep owned data, to be able to safely reference it from Value<'static> 13 | _data: String, 14 | value: Value<'static>, 15 | } 16 | 17 | impl OwnedValue { 18 | /// Validates `&[u8]` for utf-8 and parses it into a [crate::Value]. 19 | pub fn from_slice(data: &[u8]) -> io::Result { 20 | let data = String::from_utf8(data.to_vec()) 21 | .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "Invalid UTF-8"))?; 22 | Self::from_string(data) 23 | } 24 | 25 | /// Takes serialized JSON `&str` and parses it into a [crate::Value]. 26 | /// 27 | /// Clones the passed str. 28 | #[allow(clippy::should_implement_trait)] 29 | pub fn from_str(json_str: &str) -> io::Result { 30 | let json_str = json_str.to_string(); 31 | Self::from_string(json_str) 32 | } 33 | 34 | /// Takes serialized JSON `String` and parses it into a [crate::Value]. 35 | pub fn from_string(json_str: String) -> io::Result { 36 | let value: Value = serde_json::from_str(&json_str)?; 37 | let value = unsafe { extend_lifetime(value) }; 38 | Ok(Self { 39 | _data: json_str, 40 | value, 41 | }) 42 | } 43 | 44 | /// Takes serialized JSON `String` and parses it into a [crate::Value]. 45 | pub fn parse_from(json_str: String) -> io::Result { 46 | Self::from_string(json_str) 47 | } 48 | 49 | /// Returns the `Value` reference. 50 | pub fn get_value(&self) -> &Value<'_> { 51 | &self.value 52 | } 53 | } 54 | 55 | impl Deref for OwnedValue { 56 | type Target = Value<'static>; 57 | 58 | fn deref(&self) -> &Self::Target { 59 | &self.value 60 | } 61 | } 62 | 63 | unsafe fn extend_lifetime<'b>(r: Value<'b>) -> Value<'static> { 64 | std::mem::transmute::, Value<'static>>(r) 65 | } 66 | 67 | #[cfg(test)] 68 | mod tests { 69 | use super::*; 70 | 71 | /// Test reading from the internal Value via Deref. 72 | #[test] 73 | fn test_deref_access() { 74 | let raw_json = r#"{"name": "John", "age": 30}"#; 75 | let owned_value = OwnedValue::from_string(raw_json.to_string()).unwrap(); 76 | 77 | assert_eq!(owned_value.get("name"), &Value::Str("John".into())); 78 | assert_eq!(owned_value.get("age"), &Value::Number(30_u64.into())); 79 | } 80 | 81 | /// Test that clone clones OwnedValue 82 | #[test] 83 | fn test_deref_clone() { 84 | let raw_json = r#"{"name": "John", "age": 30}"#; 85 | let owned_value = OwnedValue::from_string(raw_json.to_string()).unwrap(); 86 | let owned_value = owned_value.clone(); 87 | 88 | assert_eq!(owned_value.get("name"), &Value::Str("John".into())); 89 | assert_eq!(owned_value.get("age"), &Value::Number(30_u64.into())); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/ser.rs: -------------------------------------------------------------------------------- 1 | use serde::ser::{Serialize, Serializer}; 2 | 3 | use crate::num::{Number, N}; 4 | use crate::owned::OwnedValue; 5 | use crate::value::Value; 6 | use crate::Map; 7 | 8 | impl Serialize for Value<'_> { 9 | fn serialize(&self, serializer: S) -> Result 10 | where S: Serializer { 11 | match self { 12 | Value::Null => serializer.serialize_unit(), 13 | Value::Bool(b) => serializer.serialize_bool(*b), 14 | Value::Number(n) => n.serialize(serializer), 15 | Value::Str(s) => serializer.serialize_str(s), 16 | Value::Array(v) => serializer.collect_seq(v), 17 | Value::Object(m) => m.serialize(serializer), 18 | } 19 | } 20 | } 21 | impl Serialize for Map<'_> { 22 | fn serialize(&self, serializer: S) -> Result 23 | where S: Serializer { 24 | serializer.collect_map(self.iter()) 25 | } 26 | } 27 | 28 | impl Serialize for OwnedValue { 29 | fn serialize(&self, serializer: S) -> Result 30 | where S: Serializer { 31 | Value::serialize(self.get_value(), serializer) 32 | } 33 | } 34 | 35 | impl Serialize for Number { 36 | fn serialize(&self, serializer: S) -> Result 37 | where S: Serializer { 38 | match self.n { 39 | N::PosInt(n) => serializer.serialize_u64(n), 40 | N::NegInt(n) => serializer.serialize_i64(n), 41 | N::Float(n) => serializer.serialize_f64(n), 42 | } 43 | } 44 | } 45 | 46 | #[cfg(test)] 47 | mod tests { 48 | 49 | #[test] 50 | fn serialize_json_test() { 51 | let json_obj = 52 | r#"{"bool":true,"string_key":"string_val","float":1.23,"i64":-123,"u64":123}"#; 53 | 54 | let val1: crate::Value = serde_json::from_str(json_obj).unwrap(); 55 | let deser1: String = serde_json::to_string(&val1).unwrap(); 56 | assert_eq!(deser1, json_obj); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/value.rs: -------------------------------------------------------------------------------- 1 | use core::fmt; 2 | use core::hash::Hash; 3 | use std::borrow::Cow; 4 | use std::fmt::{Debug, Display}; 5 | 6 | use crate::index::Index; 7 | use crate::num::{Number, N}; 8 | pub use crate::object_vec::ObjectAsVec; 9 | 10 | /// Represents any valid JSON value. 11 | /// 12 | /// # Example 13 | /// ``` 14 | /// use std::io; 15 | /// use serde_json_borrow::Value; 16 | /// fn main() -> io::Result<()> { 17 | /// let data = r#"{"bool": true, "key": "123"}"#; 18 | /// let value: Value = serde_json::from_str(&data)?; 19 | /// assert_eq!(value.get("bool"), &Value::Bool(true)); 20 | /// assert_eq!(value.get("key"), &Value::Str("123".into())); 21 | /// Ok(()) 22 | /// } 23 | /// ``` 24 | #[derive(Clone, Eq, PartialEq, Hash, Default)] 25 | pub enum Value<'ctx> { 26 | /// Represents a JSON null value. 27 | /// 28 | /// ``` 29 | /// # use serde_json_borrow::Value; 30 | /// # 31 | /// let v = Value::Null; 32 | /// ``` 33 | #[default] 34 | Null, 35 | 36 | /// Represents a JSON boolean. 37 | /// 38 | /// ``` 39 | /// # use serde_json_borrow::Value; 40 | /// # 41 | /// let v = Value::Bool(true); 42 | /// ``` 43 | Bool(bool), 44 | 45 | /// Represents a JSON number, whether integer or floating point. 46 | /// 47 | /// ``` 48 | /// # use serde_json_borrow::Value; 49 | /// # 50 | /// let v = Value::Number(12.5.into()); 51 | /// ``` 52 | Number(Number), 53 | 54 | /// Represents a JSON string. 55 | /// 56 | /// ``` 57 | /// # use serde_json_borrow::Value; 58 | /// # 59 | /// let v = Value::Str("ref".into()); 60 | /// ``` 61 | Str(Cow<'ctx, str>), 62 | 63 | /// Represents a JSON array. 64 | Array(Vec>), 65 | 66 | /// Represents a JSON object. 67 | /// 68 | /// By default the map is backed by a Vec. Allows very fast deserialization. 69 | /// Ideal when wanting to iterate over the values, in contrast to look up by key. 70 | /// 71 | /// ``` 72 | /// # use serde_json_borrow::Value; 73 | /// # use serde_json_borrow::ObjectAsVec; 74 | /// # 75 | /// let v = Value::Object([("key".into(), Value::Str("value".into()))].into_iter().collect::>().into()); 76 | /// ``` 77 | Object(ObjectAsVec<'ctx>), 78 | } 79 | 80 | impl<'ctx> Value<'ctx> { 81 | /// Index into a `serde_json_borrow::Value` using the syntax `value.get(0)` or 82 | /// `value.get("k")`. 83 | /// 84 | /// Returns `Value::Null` if the type of `self` does not match the type of 85 | /// the index, for example if the index is a string and `self` is an array 86 | /// or a number. Also returns `Value::Null` if the given key does not exist 87 | /// in the map or the given index is not within the bounds of the array. 88 | /// 89 | /// # Examples 90 | /// 91 | /// ``` 92 | /// # use serde_json_borrow::Value; 93 | /// # 94 | /// let json_obj = r#" 95 | /// { 96 | /// "x": { 97 | /// "y": ["z", "zz"] 98 | /// } 99 | /// } 100 | /// "#; 101 | /// 102 | /// let data: Value = serde_json::from_str(json_obj).unwrap(); 103 | /// 104 | /// assert_eq!(data.get("x").get("y").get(0), &Value::Str("z".into())); 105 | /// assert_eq!(data.get("x").get("y").get(1), &Value::Str("zz".into())); 106 | /// assert_eq!(data.get("x").get("y").get(2), &Value::Null); 107 | /// 108 | /// assert_eq!(data.get("a"), &Value::Null); 109 | /// assert_eq!(data.get("a").get("b"), &Value::Null); 110 | /// ``` 111 | #[inline] 112 | pub fn get>(&'ctx self, index: I) -> &'ctx Value<'ctx> { 113 | static NULL: Value = Value::Null; 114 | index.index_into(self).unwrap_or(&NULL) 115 | } 116 | 117 | /// Returns true if `Value` is Value::Null. 118 | pub fn is_null(&self) -> bool { 119 | matches!(self, Value::Null) 120 | } 121 | 122 | /// Returns true if `Value` is Value::Array. 123 | pub fn is_array(&self) -> bool { 124 | matches!(self, Value::Array(_)) 125 | } 126 | 127 | /// Returns true if `Value` is Value::Object. 128 | pub fn is_object(&self) -> bool { 129 | matches!(self, Value::Object(_)) 130 | } 131 | 132 | /// Returns true if `Value` is Value::Bool. 133 | pub fn is_bool(&self) -> bool { 134 | matches!(self, Value::Bool(_)) 135 | } 136 | 137 | /// Returns true if `Value` is Value::Number. 138 | pub fn is_number(&self) -> bool { 139 | matches!(self, Value::Number(_)) 140 | } 141 | 142 | /// Returns true if `Value` is Value::Str. 143 | pub fn is_string(&self) -> bool { 144 | matches!(self, Value::Str(_)) 145 | } 146 | 147 | /// Returns true if the Value is an integer between i64::MIN and i64::MAX. 148 | /// For any Value on which is_i64 returns true, as_i64 is guaranteed to return the integer 149 | /// value. 150 | pub fn is_i64(&self) -> bool { 151 | match self { 152 | Value::Number(n) => n.is_i64(), 153 | _ => false, 154 | } 155 | } 156 | 157 | /// Returns true if the Value is an integer between zero and u64::MAX. 158 | /// For any Value on which is_u64 returns true, as_u64 is guaranteed to return the integer 159 | /// value. 160 | pub fn is_u64(&self) -> bool { 161 | match self { 162 | Value::Number(n) => n.is_u64(), 163 | _ => false, 164 | } 165 | } 166 | 167 | /// Returns true if the Value is a f64 number. 168 | pub fn is_f64(&self) -> bool { 169 | match self { 170 | Value::Number(n) => n.is_f64(), 171 | _ => false, 172 | } 173 | } 174 | 175 | /// If the Value is an Array, returns an iterator over the elements in the array. 176 | pub fn iter_array(&self) -> Option>> { 177 | match self { 178 | Value::Array(arr) => Some(arr.iter()), 179 | _ => None, 180 | } 181 | } 182 | 183 | /// If the Value is an Object, returns an iterator over the elements in the object. 184 | pub fn iter_object(&self) -> Option)>> { 185 | match self { 186 | Value::Object(arr) => Some(arr.iter()), 187 | _ => None, 188 | } 189 | } 190 | 191 | /// If the Value is an Array, returns the associated Array. Returns None otherwise. 192 | pub fn as_array(&self) -> Option<&[Value<'ctx>]> { 193 | match self { 194 | Value::Array(arr) => Some(arr), 195 | _ => None, 196 | } 197 | } 198 | 199 | /// If the Value is an Object, returns the associated Object. Returns None otherwise. 200 | pub fn as_object(&self) -> Option<&ObjectAsVec<'ctx>> { 201 | match self { 202 | Value::Object(obj) => Some(obj), 203 | _ => None, 204 | } 205 | } 206 | 207 | /// If the Value is a Boolean, returns the associated bool. Returns None otherwise. 208 | pub fn as_bool(&self) -> Option { 209 | match self { 210 | Value::Bool(b) => Some(*b), 211 | _ => None, 212 | } 213 | } 214 | 215 | /// If the Value is a String, returns the associated str. Returns None otherwise. 216 | pub fn as_str(&self) -> Option<&str> { 217 | match self { 218 | Value::Str(text) => Some(text), 219 | _ => None, 220 | } 221 | } 222 | 223 | /// If the Value is an integer, represent it as i64 if possible. Returns None otherwise. 224 | pub fn as_i64(&self) -> Option { 225 | match self { 226 | Value::Number(n) => n.as_i64(), 227 | _ => None, 228 | } 229 | } 230 | 231 | /// If the Value is an integer, represent it as u64 if possible. Returns None otherwise. 232 | pub fn as_u64(&self) -> Option { 233 | match self { 234 | Value::Number(n) => n.as_u64(), 235 | _ => None, 236 | } 237 | } 238 | 239 | /// If the Value is a number, represent it as f64 if possible. Returns None otherwise. 240 | pub fn as_f64(&self) -> Option { 241 | match self { 242 | Value::Number(n) => n.as_f64(), 243 | _ => None, 244 | } 245 | } 246 | } 247 | 248 | impl From for Value<'_> { 249 | fn from(val: bool) -> Self { 250 | Value::Bool(val) 251 | } 252 | } 253 | 254 | impl<'a> From<&'a str> for Value<'a> { 255 | fn from(val: &'a str) -> Self { 256 | Value::Str(Cow::Borrowed(val)) 257 | } 258 | } 259 | 260 | impl From for Value<'_> { 261 | fn from(val: String) -> Self { 262 | Value::Str(Cow::Owned(val)) 263 | } 264 | } 265 | 266 | impl<'a, T: Into>> From> for Value<'a> { 267 | fn from(val: Vec) -> Self { 268 | Value::Array(val.into_iter().map(Into::into).collect()) 269 | } 270 | } 271 | 272 | impl<'a, T: Clone + Into>> From<&[T]> for Value<'a> { 273 | fn from(val: &[T]) -> Self { 274 | Value::Array(val.iter().map(Clone::clone).map(Into::into).collect()) 275 | } 276 | } 277 | 278 | impl Debug for Value<'_> { 279 | fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 280 | match self { 281 | Value::Null => formatter.write_str("Null"), 282 | Value::Bool(boolean) => write!(formatter, "Bool({})", boolean), 283 | Value::Number(number) => match number.n { 284 | N::PosInt(n) => write!(formatter, "Number({:?})", n), 285 | N::NegInt(n) => write!(formatter, "Number({:?})", n), 286 | N::Float(n) => write!(formatter, "Number({:?})", n), 287 | }, 288 | Value::Str(string) => write!(formatter, "Str({:?})", string), 289 | Value::Array(vec) => { 290 | formatter.write_str("Array ")?; 291 | Debug::fmt(vec, formatter) 292 | } 293 | Value::Object(map) => { 294 | formatter.write_str("Object ")?; 295 | Debug::fmt(map, formatter) 296 | } 297 | } 298 | } 299 | } 300 | 301 | // We just convert to serde_json::Value to Display 302 | impl Display for Value<'_> { 303 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 304 | write!(f, "{}", serde_json::Value::from(self.clone())) 305 | } 306 | } 307 | 308 | impl From for Value<'_> { 309 | fn from(val: u64) -> Self { 310 | Value::Number(val.into()) 311 | } 312 | } 313 | 314 | impl From for Value<'_> { 315 | fn from(val: i64) -> Self { 316 | Value::Number(val.into()) 317 | } 318 | } 319 | 320 | impl From for Value<'_> { 321 | fn from(val: f64) -> Self { 322 | Value::Number(val.into()) 323 | } 324 | } 325 | 326 | impl From> for serde_json::Value { 327 | fn from(val: Value) -> Self { 328 | match val { 329 | Value::Null => serde_json::Value::Null, 330 | Value::Bool(val) => serde_json::Value::Bool(val), 331 | Value::Number(val) => serde_json::Value::Number(val.into()), 332 | Value::Str(val) => serde_json::Value::String(val.to_string()), 333 | Value::Array(vals) => { 334 | serde_json::Value::Array(vals.into_iter().map(|val| val.into()).collect()) 335 | } 336 | Value::Object(vals) => serde_json::Value::Object(vals.into()), 337 | } 338 | } 339 | } 340 | 341 | impl From<&Value<'_>> for serde_json::Value { 342 | fn from(val: &Value) -> Self { 343 | match val { 344 | Value::Null => serde_json::Value::Null, 345 | Value::Bool(val) => serde_json::Value::Bool(*val), 346 | Value::Number(val) => serde_json::Value::Number((*val).into()), 347 | Value::Str(val) => serde_json::Value::String(val.to_string()), 348 | Value::Array(vals) => { 349 | serde_json::Value::Array(vals.iter().map(|val| val.into()).collect()) 350 | } 351 | Value::Object(vals) => serde_json::Value::Object(vals.into()), 352 | } 353 | } 354 | } 355 | 356 | impl<'ctx> From<&'ctx serde_json::Value> for Value<'ctx> { 357 | fn from(value: &'ctx serde_json::Value) -> Self { 358 | match value { 359 | serde_json::Value::Null => Value::Null, 360 | serde_json::Value::Bool(b) => Value::Bool(*b), 361 | serde_json::Value::Number(n) => { 362 | if let Some(n) = n.as_i64() { 363 | Value::Number(n.into()) 364 | } else if let Some(n) = n.as_u64() { 365 | Value::Number(n.into()) 366 | } else if let Some(n) = n.as_f64() { 367 | Value::Number(n.into()) 368 | } else { 369 | unreachable!() 370 | } 371 | } 372 | serde_json::Value::String(val) => Value::Str(Cow::Borrowed(val)), 373 | serde_json::Value::Array(arr) => { 374 | let out: Vec> = arr.iter().map(|v| v.into()).collect(); 375 | Value::Array(out) 376 | } 377 | serde_json::Value::Object(obj) => { 378 | let mut ans = ObjectAsVec::default(); 379 | for (k, v) in obj { 380 | ans.insert(k.as_str(), v.into()); 381 | } 382 | Value::Object(ans) 383 | } 384 | } 385 | } 386 | } 387 | 388 | #[cfg(test)] 389 | mod tests { 390 | use std::io; 391 | 392 | use super::*; 393 | 394 | #[test] 395 | fn from_serde() { 396 | let value = &serde_json::json!({ 397 | "a": 1, 398 | "b": "2", 399 | "c": [3, 4], 400 | "d": {"e": "alo"} 401 | }); 402 | 403 | let value: Value = value.into(); 404 | assert_eq!(value.get("a"), &Value::Number(1i64.into())); 405 | assert_eq!(value.get("b"), &Value::Str("2".into())); 406 | assert_eq!(value.get("c").get(0), &Value::Number(3i64.into())); 407 | assert_eq!(value.get("c").get(1), &Value::Number(4i64.into())); 408 | assert_eq!(value.get("d").get("e"), &Value::Str("alo".into())); 409 | } 410 | 411 | #[test] 412 | fn number_test() -> io::Result<()> { 413 | let data = r#"{"val1": 123.5, "val2": 123, "val3": -123}"#; 414 | let value: Value = serde_json::from_str(data)?; 415 | assert!(value.get("val1").is_f64()); 416 | assert!(!value.get("val1").is_u64()); 417 | assert!(!value.get("val1").is_i64()); 418 | 419 | assert!(!value.get("val2").is_f64()); 420 | assert!(value.get("val2").is_u64()); 421 | assert!(value.get("val2").is_i64()); 422 | 423 | assert!(!value.get("val3").is_f64()); 424 | assert!(!value.get("val3").is_u64()); 425 | assert!(value.get("val3").is_i64()); 426 | 427 | assert!(value.get("val1").as_f64().is_some()); 428 | assert!(value.get("val2").as_f64().is_some()); 429 | assert!(value.get("val3").as_f64().is_some()); 430 | 431 | assert!(value.get("val1").as_u64().is_none()); 432 | assert!(value.get("val2").as_u64().is_some()); 433 | assert!(value.get("val3").as_u64().is_none()); 434 | 435 | assert!(value.get("val1").as_i64().is_none()); 436 | assert!(value.get("val2").as_i64().is_some()); 437 | assert!(value.get("val3").as_i64().is_some()); 438 | 439 | Ok(()) 440 | } 441 | } 442 | --------------------------------------------------------------------------------