persy_expimp/
json.rs

1extern crate data_encoding;
2use crate::{
3    export, export_from_snapshot, import,
4    serde::{index_type_id_from_string, index_type_id_to_string},
5    EIRes, Entry, IndexKey, IndexMetadata, IndexValue, Info, Record, SegmentMetadata,
6};
7use data_encoding::BASE64;
8use data_encoding::BASE64URL_NOPAD;
9use persy::{ByteVec, IndexId, Persy, PersyId, SegmentId, Snapshot, ValueMode};
10use serde_json::{json, Value as JsonValue};
11use std::io::{BufRead, BufReader, Read, Write};
12use std::ops::Deref;
13use std::string::ToString;
14
15fn parse_byte_vec(s: &str) -> Option<ByteVec> {
16    BASE64URL_NOPAD.decode(s.as_bytes()).ok().map(|v| ByteVec::new(v))
17}
18fn byte_vec_to_string(val: ByteVec) -> String {
19    BASE64URL_NOPAD.encode(val.deref())
20}
21fn json_key(key: IndexKey) -> JsonValue {
22    match key {
23        IndexKey::U8(k) => json!({"type":"u8","value":k}),
24        IndexKey::U16(k) => json!({"type":"u16","value":k}),
25        IndexKey::U32(k) => json!({"type":"u32","value":k}),
26        IndexKey::U64(k) => json!({"type":"u64","value":k}),
27        IndexKey::U128(k) => json!({"type":"u128","value":k.to_string()}),
28        IndexKey::I8(k) => json!({"type":"i8","value":k}),
29        IndexKey::I16(k) => json!({"type":"i16","value":k}),
30        IndexKey::I32(k) => json!({"type":"i32","value":k}),
31        IndexKey::I64(k) => json!({"type":"i64","value":k}),
32        IndexKey::I128(k) => json!({"type":"i128","value":k.to_string()}),
33        IndexKey::F32(k) => json!({"type":"f32","value":k}),
34        IndexKey::F64(k) => json!({"type":"f64","value":k}),
35        IndexKey::String(k) => json!({"type":"String","value":k}),
36        IndexKey::PersyId(k) => json!({"type":"PersyId","value":k.to_string()}),
37        IndexKey::ByteVec(k) => json!({"type":"ByteVec","value":byte_vec_to_string(k)}),
38    }
39}
40
41fn json_value(key: IndexValue) -> JsonValue {
42    match key {
43        IndexValue::U8(k) => json!({"type":"u8","value":k.into_iter().collect::<Vec<u8>>()}),
44        IndexValue::U16(k) => json!({"type":"u16","value":k.into_iter().collect::<Vec<u16>>()}),
45        IndexValue::U32(k) => json!({"type":"u32","value":k.into_iter().collect::<Vec<u32>>()}),
46        IndexValue::U64(k) => json!({"type":"u64","value":k.into_iter().collect::<Vec<u64>>()}),
47        IndexValue::U128(k) => {
48            json!({"type":"u128","value":k.into_iter().map(|x|x.to_string()).collect::<Vec<String>>()})
49        }
50        IndexValue::I8(k) => json!({"type":"i8","value":k.into_iter().collect::<Vec<i8>>()}),
51        IndexValue::I16(k) => json!({"type":"i16","value":k.into_iter().collect::<Vec<i16>>()}),
52        IndexValue::I32(k) => json!({"type":"i32","value":k.into_iter().collect::<Vec<i32>>()}),
53        IndexValue::I64(k) => json!({"type":"i64","value":k.into_iter().collect::<Vec<i64>>()}),
54        IndexValue::I128(k) => {
55            json!({"type":"i128","value":k.into_iter().map(|x|x.to_string()).collect::<Vec<String>>()})
56        }
57        IndexValue::F32(k) => json!({"type":"f32","value":k.into_iter().collect::<Vec<f32>>()}),
58        IndexValue::F64(k) => json!({"type":"f64","value":k.into_iter().collect::<Vec<f64>>()}),
59        IndexValue::String(k) => json!({"type":"String","value":k.into_iter().collect::<Vec<String>>()}),
60        IndexValue::PersyId(k) => {
61            json!({"type":"PersyId","value":k.into_iter().map(|x|x.to_string()).collect::<Vec<String>>()})
62        }
63        IndexValue::ByteVec(k) => {
64            json!({"type":"ByteVec","value":k.into_iter().map(|x|byte_vec_to_string(x)).collect::<Vec<String>>()})
65        }
66    }
67}
68
69///
70/// Export the data from a persy storage with using JSON format
71///
72/// # Example
73/// ```
74/// use persy::{Persy, Config};
75/// use persy_expimp::export_json;
76/// use std::vec::Vec;
77/// use std::fs::OpenOptions;
78///
79/// # use persy_expimp::EIRes;
80/// # fn foo() -> EIRes<()> {
81/// let persy = Persy::open("file.persy", Config::new())?;
82/// let mut output = OpenOptions::new().write(true).create(true).open("dest.json")?;
83/// export_json(&persy, &mut output)?;
84/// # Ok(())
85/// # }
86/// ```
87pub fn export_json(persy: &Persy, write: &mut dyn Write) -> EIRes<()> {
88    export_json_impl(export(persy)?, write)
89}
90
91///
92/// Export the data from a persy storage with using JSON format
93///
94/// # Example
95/// ```
96/// use persy::{Persy, Config};
97/// use persy_expimp::export_json_from_snapshot;
98/// use std::vec::Vec;
99/// use std::fs::OpenOptions;
100///
101/// # use persy_expimp::EIRes;
102/// # fn foo() -> EIRes<()> {
103/// let persy = Persy::open("file.persy", Config::new())?;
104/// let snapshot = persy.snapshot()?;
105/// let mut output = OpenOptions::new().write(true).create(true).open("dest.json")?;
106/// export_json_from_snapshot(&snapshot, &mut output)?;
107/// # Ok(())
108/// # }
109/// ```
110pub fn export_json_from_snapshot(snapshot: &Snapshot, write: &mut dyn Write) -> EIRes<()> {
111    export_json_impl(export_from_snapshot(snapshot)?, write)
112}
113
114fn export_json_impl(data: Box<impl Iterator<Item = Info>>, write: &mut dyn Write) -> EIRes<()> {
115    for val in data {
116        let to_write = match val {
117            Info::Segment(segment) => json!({
118                "type":"segment",
119                "version": segment.version,
120                "value": {
121                    "name":segment.name,
122                    "id":segment.id.to_string(),
123                }
124            }),
125            Info::Record(record) => json!({
126                "type":"record",
127                "version": record.version,
128                "value": {
129                    "segment":record.segment,
130                    "id" : record.id.to_string(),
131                    "content":BASE64.encode(&record.content)
132                }
133            }),
134            Info::Index(index) => {
135                let value_mode = match index.value_mode {
136                    ValueMode::Replace => "replace",
137                    ValueMode::Cluster => "cluster",
138                    ValueMode::Exclusive => "exclusive",
139                };
140                json!({
141                    "type":"index",
142                    "version": index.version,
143                    "value": {
144                        "name":index.name,
145                        "id":index.id.to_string(),
146                        "key_type":index_type_id_to_string(index.key_type),
147                        "value_type":index_type_id_to_string(index.value_type),
148                        "value_mode":value_mode
149                    }
150                })
151            }
152            Info::Entry(entry) => json!({
153                "type":"entry",
154                "version": entry.version,
155                "value": {
156                    "index":entry.index,
157                    "key":json_key(entry.key),
158                    "value":json_value(entry.value),
159                }
160            }),
161        };
162        writeln!(write, "{}", serde_json::to_string(&to_write)?)?;
163    }
164    Ok(())
165}
166
167fn translate_value_mode(value: &str) -> Option<ValueMode> {
168    match value {
169        "replace" => Some(ValueMode::Replace),
170        "cluster" => Some(ValueMode::Cluster),
171        "exclusive" => Some(ValueMode::Exclusive),
172        _ => None,
173    }
174}
175
176fn translate_key(value: &JsonValue) -> Option<IndexKey> {
177    let ob = value.as_object();
178    if let Some(obj) = ob {
179        let t = obj.get("type").into_iter().filter_map(|x| x.as_str()).next();
180        let v = obj.get("value");
181        match (t, v) {
182            (Some("u8"), Some(val)) => val.as_u64().map(|uv| IndexKey::U8(uv as u8)),
183            (Some("u16"), Some(val)) => val.as_u64().map(|uv| IndexKey::U16(uv as u16)),
184            (Some("u32"), Some(val)) => val.as_u64().map(|uv| IndexKey::U32(uv as u32)),
185            (Some("u64"), Some(val)) => val.as_u64().map(|uv| IndexKey::U64(uv as u64)),
186            (Some("u128"), Some(val)) => val
187                .as_str()
188                .map(|s| s.parse::<u128>().ok())
189                .iter()
190                .flatten()
191                .map(|z| *z)
192                .next()
193                .map(|uv| IndexKey::U128(uv as u128)),
194            (Some("i8"), Some(val)) => val.as_i64().map(|uv| IndexKey::I8(uv as i8)),
195            (Some("i16"), Some(val)) => val.as_i64().map(|uv| IndexKey::I16(uv as i16)),
196            (Some("i32"), Some(val)) => val.as_i64().map(|uv| IndexKey::I32(uv as i32)),
197            (Some("i64"), Some(val)) => val.as_i64().map(|uv| IndexKey::I64(uv as i64)),
198            (Some("i128"), Some(val)) => val
199                .as_str()
200                .map(|s| s.parse::<i128>().ok())
201                .iter()
202                .flatten()
203                .map(|z| *z)
204                .next()
205                .map(|uv| IndexKey::I128(uv as i128)),
206            (Some("f32"), Some(val)) => val.as_f64().map(|uv| IndexKey::F32(uv as f32)),
207            (Some("f64"), Some(val)) => val.as_f64().map(|uv| IndexKey::F64(uv as f64)),
208            (Some("String"), Some(val)) => val.as_str().map(|uv| IndexKey::String(uv.to_string())),
209            (Some("PersyId"), Some(val)) => val
210                .as_str()
211                .map(|uv| uv.parse::<PersyId>().ok().map(IndexKey::PersyId))
212                .into_iter()
213                .flatten()
214                .next(),
215            (Some("ByteVec"), Some(val)) => val
216                .as_str()
217                .map(|uv| parse_byte_vec(uv).map(IndexKey::ByteVec))
218                .into_iter()
219                .flatten()
220                .next(),
221            _ => None,
222        }
223    } else {
224        None
225    }
226}
227
228fn translate_value(value: &JsonValue) -> Option<IndexValue> {
229    let ob = value.as_object();
230    if let Some(obj) = ob {
231        let t = obj.get("type").into_iter().filter_map(|x| x.as_str()).next();
232        let v = obj.get("value");
233        match (t, v) {
234            (Some("u8"), Some(val)) => val
235                .as_array()
236                .map(|v| {
237                    v.into_iter()
238                        .filter_map(|x| x.as_u64())
239                        .map(|x| x as u8)
240                        .collect::<Vec<u8>>()
241                })
242                .map(|v| IndexValue::U8(v)),
243            (Some("u16"), Some(val)) => val
244                .as_array()
245                .map(|v| {
246                    v.into_iter()
247                        .filter_map(|x| x.as_u64())
248                        .map(|x| x as u16)
249                        .collect::<Vec<u16>>()
250                })
251                .map(|v| IndexValue::U16(v)),
252            (Some("u32"), Some(val)) => val
253                .as_array()
254                .map(|v| {
255                    v.into_iter()
256                        .filter_map(|x| x.as_u64())
257                        .map(|x| x as u32)
258                        .collect::<Vec<u32>>()
259                })
260                .map(|v| IndexValue::U32(v)),
261            (Some("u64"), Some(val)) => val
262                .as_array()
263                .map(|v| {
264                    v.into_iter()
265                        .filter_map(|x| {
266                            if x.is_string() {
267                                x.as_str()
268                                    .map(|s| s.parse::<u64>().ok())
269                                    .iter()
270                                    .flatten()
271                                    .map(|z| *z)
272                                    .next()
273                            } else {
274                                x.as_u64()
275                            }
276                        })
277                        .collect::<Vec<u64>>()
278                })
279                .map(|v| IndexValue::U64(v)),
280            (Some("u128"), Some(val)) => val
281                .as_array()
282                .map(|v| {
283                    v.into_iter()
284                        .filter_map(|x| {
285                            x.as_str()
286                                .map(|s| s.parse::<u128>().ok())
287                                .iter()
288                                .flatten()
289                                .map(|z| *z)
290                                .next()
291                        })
292                        .collect::<Vec<u128>>()
293                })
294                .map(|v| IndexValue::U128(v)),
295            (Some("i8"), Some(val)) => val
296                .as_array()
297                .map(|v| {
298                    v.into_iter()
299                        .filter_map(|x| x.as_i64())
300                        .map(|x| x as i8)
301                        .collect::<Vec<i8>>()
302                })
303                .map(|v| IndexValue::I8(v)),
304            (Some("i16"), Some(val)) => val
305                .as_array()
306                .map(|v| {
307                    v.into_iter()
308                        .filter_map(|x| x.as_i64())
309                        .map(|x| x as i16)
310                        .collect::<Vec<i16>>()
311                })
312                .map(|v| IndexValue::I16(v)),
313            (Some("i32"), Some(val)) => val
314                .as_array()
315                .map(|v| {
316                    v.into_iter()
317                        .filter_map(|x| x.as_i64())
318                        .map(|x| x as i32)
319                        .collect::<Vec<i32>>()
320                })
321                .map(|v| IndexValue::I32(v)),
322            (Some("i64"), Some(val)) => val
323                .as_array()
324                .map(|v| {
325                    v.into_iter()
326                        .filter_map(|x| {
327                            if x.is_string() {
328                                x.as_str()
329                                    .map(|s| s.parse::<i64>().ok())
330                                    .iter()
331                                    .flatten()
332                                    .map(|z| *z)
333                                    .next()
334                            } else {
335                                x.as_i64()
336                            }
337                        })
338                        .collect::<Vec<i64>>()
339                })
340                .map(|v| IndexValue::I64(v)),
341            (Some("i128"), Some(val)) => val
342                .as_array()
343                .map(|v| {
344                    v.into_iter()
345                        .filter_map(|x| {
346                            x.as_str()
347                                .map(|s| s.parse::<i128>().ok())
348                                .iter()
349                                .flatten()
350                                .map(|z| *z)
351                                .next()
352                        })
353                        .collect::<Vec<i128>>()
354                })
355                .map(|v| IndexValue::I128(v)),
356            (Some("f32"), Some(val)) => val
357                .as_array()
358                .map(|v| {
359                    v.into_iter()
360                        .filter_map(|x| x.as_f64())
361                        .map(|x| x as f32)
362                        .collect::<Vec<f32>>()
363                })
364                .map(|v| IndexValue::F32(v)),
365            (Some("f64"), Some(val)) => val
366                .as_array()
367                .map(|v| v.into_iter().filter_map(|x| x.as_f64()).collect::<Vec<f64>>())
368                .map(|v| IndexValue::F64(v)),
369            (Some("String"), Some(val)) => val
370                .as_array()
371                .map(|v| {
372                    v.into_iter()
373                        .filter_map(|x| x.as_str())
374                        .map(|x| x.to_string())
375                        .collect::<Vec<String>>()
376                })
377                .map(|v| IndexValue::String(v)),
378            (Some("PersyId"), Some(val)) => val
379                .as_array()
380                .map(|v| {
381                    v.into_iter()
382                        .filter_map(|x| x.as_str())
383                        .filter_map(|uv| uv.parse::<PersyId>().ok())
384                        .collect::<Vec<PersyId>>()
385                })
386                .map(|v| IndexValue::PersyId(v)),
387            (Some("ByteVec"), Some(val)) => val
388                .as_array()
389                .map(|v| {
390                    v.into_iter()
391                        .filter_map(|x| x.as_str())
392                        .filter_map(|uv| parse_byte_vec(uv))
393                        .collect::<Vec<ByteVec>>()
394                })
395                .map(|v| IndexValue::ByteVec(v)),
396            _ => None,
397        }
398    } else {
399        None
400    }
401}
402
403fn translate_content(value: &JsonValue) -> Option<Vec<u8>> {
404    value
405        .as_str()
406        .into_iter()
407        .filter_map(|v| BASE64.decode(v.as_bytes()).ok())
408        .next()
409}
410
411fn translate_line(line: &str) -> Option<Info> {
412    let value: Result<JsonValue, _> = serde_json::from_str(&line);
413    if let Some(Some(r)) = value.map(|x| x.as_object().cloned()).ok() {
414        let t = r.get("type").map(|x| x.as_str());
415        let v = r.get("value").map(|x| x.as_object());
416        let vers = r.get("version").map(|x| x.as_u64().map(|v| v as u32));
417
418        match (t, v, vers) {
419            (Some(Some("segment")), Some(Some(obj)), Some(Some(version))) => {
420                let name = obj.get("name").into_iter().filter_map(|x| x.as_str()).next();
421                let id = obj
422                    .get("id")
423                    .into_iter()
424                    .filter_map(|x| x.as_str())
425                    .filter_map(|x| x.parse::<SegmentId>().ok())
426                    .next();
427                match (id, name) {
428                    (Some(val_id), Some(val_name)) => Some(Info::Segment(SegmentMetadata {
429                        version,
430                        name: val_name.to_string(),
431                        id: val_id,
432                    })),
433                    _ => None,
434                }
435            }
436            (Some(Some("record")), Some(Some(obj)), Some(Some(version))) => {
437                let segment = obj.get("segment").into_iter().filter_map(|x| x.as_str()).next();
438                let id = obj
439                    .get("id")
440                    .into_iter()
441                    .filter_map(|x| x.as_str())
442                    .filter_map(|x| x.parse::<PersyId>().ok())
443                    .next();
444                let content = obj.get("content").into_iter().filter_map(translate_content).next();
445                match (segment, id, content) {
446                    (Some(val_segment), Some(val_id), Some(val_content)) => Some(Info::Record(Record {
447                        version,
448                        segment: val_segment.to_string(),
449                        id: val_id,
450                        content: val_content,
451                    })),
452                    _ => None,
453                }
454            }
455            (Some(Some("index")), Some(Some(obj)), Some(Some(version))) => {
456                let name = obj.get("name").into_iter().filter_map(|x| x.as_str()).next();
457                let id = obj
458                    .get("id")
459                    .into_iter()
460                    .filter_map(|x| x.as_str())
461                    .filter_map(|x| x.parse::<IndexId>().ok())
462                    .next();
463                let key_type = obj
464                    .get("key_type")
465                    .into_iter()
466                    .filter_map(|x| x.as_str())
467                    .filter_map(|x| index_type_id_from_string(x))
468                    .next();
469                let value_type = obj
470                    .get("value_type")
471                    .into_iter()
472                    .filter_map(|x| x.as_str())
473                    .filter_map(|x| index_type_id_from_string(x))
474                    .next();
475                let value_mode = obj
476                    .get("value_mode")
477                    .into_iter()
478                    .filter_map(|x| x.as_str())
479                    .filter_map(translate_value_mode)
480                    .next();
481                match (id, name, key_type, value_type, value_mode) {
482                    (Some(val_id), Some(val_name), Some(val_key_type), Some(val_value_type), Some(val_value_mode)) => {
483                        Some(Info::Index(IndexMetadata {
484                            version,
485                            name: val_name.to_string(),
486                            id: val_id,
487                            key_type: val_key_type,
488                            value_type: val_value_type,
489                            value_mode: val_value_mode,
490                        }))
491                    }
492                    _ => None,
493                }
494            }
495            (Some(Some("entry")), Some(Some(obj)), Some(Some(version))) => {
496                let index = obj.get("index").into_iter().filter_map(|x| x.as_str()).next();
497                let key = obj.get("key").into_iter().filter_map(translate_key).next();
498                let value = obj.get("value").into_iter().filter_map(translate_value).next();
499                match (index, key, value) {
500                    (Some(val_index), Some(val_key), Some(val_value)) => Some(Info::Entry(Entry {
501                        version,
502                        index: val_index.to_string(),
503                        key: val_key,
504                        value: val_value,
505                    })),
506                    _ => None,
507                }
508            }
509            _ => None,
510        }
511    } else {
512        None
513    }
514}
515
516/// Import data to a persy storage reading JSON export
517///
518///
519/// ```
520/// use persy::{Persy, Config};
521/// use persy_expimp::import_json;
522/// use std::fs::OpenOptions;
523/// # use persy_expimp::EIRes;
524///  
525/// # fn foo() -> EIRes<()> {
526/// Persy::create("imported.persy")?;
527/// let persy = Persy::open("imported.persy", Config::new())?;
528/// let mut input = OpenOptions::new().read(true).open("file_source.json")?;
529/// import_json(&persy,&mut input)?;
530/// # Ok(())
531/// # }
532/// ```
533///
534pub fn import_json(persy: &Persy, read: &mut dyn Read) -> EIRes<()> {
535    let reader = BufReader::new(read);
536    let source = reader.lines().filter_map(|l| {
537        if let Ok(line) = l {
538            let info = translate_line(&line);
539            if info.is_none() {
540                println!(" Skipping invalid line: {}", line);
541            }
542            info
543        } else {
544            None
545        }
546    });
547    import(persy, source)?;
548
549    Ok(())
550}
551#[cfg(test)]
552mod tests {
553    use super::{export_json, export_json_from_snapshot, import_json};
554    use persy::{ByteVec, Config, IndexType, Persy, PersyId, Transaction, ValueMode};
555    use std::fs;
556    use std::fs::File;
557    use std::io::Cursor;
558    use std::io::Read;
559
560    fn util<C, V>(name: &str, create: C, verify: V)
561    where
562        C: FnOnce(&mut Transaction),
563        V: FnOnce(&Persy),
564    {
565        let c_name = format!("target/{}.pei", name);
566        let rec_name = format!("target/{}_fill.pei", name);
567        Persy::create(c_name.to_string()).expect("creation works fine");
568        let p = Persy::open(c_name.to_string(), Config::new()).expect("open fine");
569        let mut tx = p.begin().unwrap();
570        create(&mut tx);
571        let prep = tx.prepare().unwrap();
572        prep.commit().unwrap();
573        let mut data = Vec::new();
574        export_json(&p, &mut data).unwrap();
575        //std::fs::write("fixtures/0.8_1.0_all.json", String::from_utf8(data.clone()).unwrap()).unwrap();
576        Persy::create(rec_name.to_string()).expect("creation works fine");
577        let p1 = Persy::open(rec_name.to_string(), Config::new()).expect("open fine");
578        import_json(&p1, &mut Cursor::new(data)).unwrap();
579        verify(&p1);
580        fs::remove_file(c_name).unwrap();
581        fs::remove_file(rec_name).unwrap();
582    }
583
584    #[test]
585    fn base_snapshot_export_import_json() {
586        let name = "json_snapshot";
587        let c_name = format!("target/{}.pei", name);
588        let rec_name = format!("target/{}_fill.pei", name);
589        Persy::create(c_name.to_string()).expect("creation works fine");
590        let p = Persy::open(c_name.to_string(), Config::new()).expect("open fine");
591        let mut tx = p.begin().unwrap();
592        tx.create_segment("test").unwrap();
593        tx.insert("test", &"test".to_string().as_bytes()).unwrap();
594        tx.create_index::<u8, u8>("test_u8", ValueMode::Replace).unwrap();
595        tx.put::<u8, u8>("test_u8", 10, 10).unwrap();
596        let prep = tx.prepare().unwrap();
597        prep.commit().unwrap();
598        let mut data = Vec::new();
599        export_json_from_snapshot(&p.snapshot().unwrap(), &mut data).expect("export works correctly");
600
601        Persy::create(rec_name.to_string()).expect("creation works fine");
602        let p1 = Persy::open(rec_name.to_string(), Config::new()).expect("open fine");
603        import_json(&p1, &mut Cursor::new(data)).unwrap();
604
605        for (_, content) in p.scan("test").unwrap() {
606            assert_eq!("test".to_string().as_bytes().to_vec(), content);
607        }
608        check_key_value(&p1, "test_u8", 10 as u8, 10 as u8);
609        fs::remove_file(c_name).unwrap();
610        fs::remove_file(rec_name).unwrap();
611    }
612
613    #[test]
614    fn all_data_export_import() {
615        util(
616            "json_all_data",
617            |tx| {
618                tx.create_segment("test").unwrap();
619                let persy_id = tx.insert("test", &"test".to_string().as_bytes()).unwrap();
620                tx.create_index::<u8, u8>("test_u8", ValueMode::Replace).unwrap();
621                tx.put::<u8, u8>("test_u8", 10, 10).unwrap();
622                tx.create_index::<u16, u16>("test_u16", ValueMode::Replace).unwrap();
623                tx.put::<u16, u16>("test_u16", 10, 10).unwrap();
624                tx.create_index::<u32, u32>("test_u32", ValueMode::Replace).unwrap();
625                tx.put::<u32, u32>("test_u32", 10, 10).unwrap();
626                tx.create_index::<u64, u64>("test_u64", ValueMode::Replace).unwrap();
627                tx.put::<u64, u64>("test_u64", 10, 10).unwrap();
628                tx.create_index::<u128, u128>("test_u128", ValueMode::Replace).unwrap();
629                tx.put::<u128, u128>("test_u128", 10, 10).unwrap();
630                tx.create_index::<i8, i8>("test_i8", ValueMode::Replace).unwrap();
631                tx.put::<i8, i8>("test_i8", 10, 10).unwrap();
632                tx.create_index::<i16, i16>("test_i16", ValueMode::Replace).unwrap();
633                tx.put::<i16, i16>("test_i16", 10, 10).unwrap();
634                tx.create_index::<i32, i32>("test_i32", ValueMode::Replace).unwrap();
635                tx.put::<i32, i32>("test_i32", 10, 10).unwrap();
636                tx.create_index::<i64, i64>("test_i64", ValueMode::Replace).unwrap();
637                tx.put::<i64, i64>("test_i64", 10, 10).unwrap();
638                tx.create_index::<i128, i128>("test_i128", ValueMode::Replace).unwrap();
639                tx.put::<i128, i128>("test_i128", 10, 10).unwrap();
640                tx.create_index::<f32, f32>("test_f32", ValueMode::Replace).unwrap();
641                tx.put::<f32, f32>("test_f32", 10.0, 10.0).unwrap();
642                tx.create_index::<f64, f64>("test_f64", ValueMode::Replace).unwrap();
643                tx.put::<f64, f64>("test_f64", 10.0, 10.0).unwrap();
644                tx.create_index::<String, String>("test_string", ValueMode::Replace)
645                    .unwrap();
646                tx.put::<String, String>("test_string", "one".to_string(), "two".to_string())
647                    .unwrap();
648                tx.create_index::<ByteVec, ByteVec>("test_bytevec", ValueMode::Replace)
649                    .unwrap();
650                let bv = ByteVec::new(vec![20, 10]);
651                let bv1 = ByteVec::new(vec![10, 20]);
652                tx.put::<ByteVec, ByteVec>("test_bytevec", bv, bv1).unwrap();
653                tx.create_index::<PersyId, PersyId>("test_p", ValueMode::Replace)
654                    .unwrap();
655                tx.put::<PersyId, PersyId>("test_p", persy_id.clone(), persy_id)
656                    .unwrap();
657            },
658            |p| {
659                for (_, content) in p.scan("test").unwrap() {
660                    assert_eq!("test".to_string().as_bytes().to_vec(), content);
661                }
662                check_key_value(p, "test_u8", 10 as u8, 10 as u8);
663                check_key_value(p, "test_u16", 10 as u16, 10 as u16);
664                check_key_value(p, "test_u32", 10 as u32, 10 as u32);
665                check_key_value(p, "test_u64", 10 as u64, 10 as u64);
666                check_key_value(p, "test_u128", 10 as u128, 10 as u128);
667                check_key_value(p, "test_i8", 10 as i8, 10 as i8);
668                check_key_value(p, "test_i16", 10 as i16, 10 as i16);
669                check_key_value(p, "test_i32", 10 as i32, 10 as i32);
670                check_key_value(p, "test_i64", 10 as i64, 10 as i64);
671                check_key_value(p, "test_i128", 10 as i128, 10 as i128);
672                check_key_value(p, "test_f32", 10 as f32, 10 as f32);
673                check_key_value(p, "test_f64", 10 as f64, 10 as f64);
674                check_key_value(p, "test_string", "one".to_string(), "two".to_string());
675                let bv = ByteVec::new(vec![20, 10]);
676                let bv1 = ByteVec::new(vec![10, 20]);
677                check_key_value(p, "test_bytevec", bv, bv1);
678                assert_eq!(
679                    1,
680                    p.range::<PersyId, PersyId, _>("test_p", ..)
681                        .unwrap()
682                        .into_iter()
683                        .count()
684                );
685            },
686        );
687    }
688
689    pub fn check_key_value<K: IndexType + PartialEq, V: IndexType + PartialEq + std::fmt::Debug>(
690        p: &Persy,
691        index: &str,
692        k: K,
693        v: V,
694    ) {
695        assert_eq!(v, p.get::<K, V>(index, &k).unwrap().into_iter().next().unwrap());
696    }
697
698    #[test]
699    pub fn test_import_01_05() {
700        Persy::create("import_from_01_05.persy").expect("creation works fine");
701        let p = &Persy::open("import_from_01_05.persy", Config::new()).expect("open fine");
702        let mut f = File::open("fixtures/0.1_0.5_all.json").expect("open correctly the file");
703        let mut data = String::new();
704
705        f.read_to_string(&mut data).expect("read all fine");
706        import_json(p, &mut Cursor::new(data)).unwrap();
707        for (_, content) in p.scan("test").unwrap() {
708            assert_eq!("test".to_string().as_bytes().to_vec(), content);
709        }
710        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
711        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
712        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
713        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
714        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
715        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
716        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
717        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
718        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
719        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
720        assert_eq!(
721            1,
722            p.range::<PersyId, PersyId, _>("test_p", ..)
723                .unwrap()
724                .into_iter()
725                .count()
726        );
727        fs::remove_file("import_from_01_05.persy").unwrap();
728    }
729
730    #[test]
731    pub fn test_import_02_06() {
732        Persy::create("import_from_02_06.persy").expect("creation works fine");
733        let p = &Persy::open("import_from_02_06.persy", Config::new()).expect("open fine");
734        let mut f = File::open("fixtures/0.2_0.6_all.json").expect("open correctly the file");
735        let mut data = String::new();
736
737        f.read_to_string(&mut data).expect("read all fine");
738        import_json(p, &mut Cursor::new(data)).unwrap();
739        for (_, content) in p.scan("test").unwrap() {
740            assert_eq!("test".to_string().as_bytes().to_vec(), content);
741        }
742        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
743        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
744        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
745        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
746        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
747        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
748        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
749        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
750        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
751        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
752        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
753        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
754        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
755        assert_eq!(
756            1,
757            p.range::<PersyId, PersyId, _>("test_p", ..)
758                .unwrap()
759                .into_iter()
760                .count()
761        );
762        fs::remove_file("import_from_02_06.persy").unwrap();
763    }
764
765    #[test]
766    pub fn test_import_03_07() {
767        Persy::create("import_from_03_07.persy").expect("creation works fine");
768        let p = &Persy::open("import_from_03_07.persy", Config::new()).expect("open fine");
769        let mut f = File::open("fixtures/0.3_0.7_all.json").expect("open correctly the file");
770        let mut data = String::new();
771
772        f.read_to_string(&mut data).expect("read all fine");
773        import_json(p, &mut Cursor::new(data)).unwrap();
774        for (_, content) in p.scan("test").unwrap() {
775            assert_eq!("test".to_string().as_bytes().to_vec(), content);
776        }
777        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
778        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
779        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
780        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
781        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
782        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
783        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
784        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
785        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
786        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
787        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
788        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
789        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
790        let bv = ByteVec::new(vec![20, 10]);
791        let bv1 = ByteVec::new(vec![10, 20]);
792        check_key_value(p, "test_bytevec", bv, bv1);
793        assert_eq!(
794            1,
795            p.range::<PersyId, PersyId, _>("test_p", ..)
796                .unwrap()
797                .into_iter()
798                .count()
799        );
800        fs::remove_file("import_from_03_07.persy").unwrap();
801    }
802
803    #[test]
804    pub fn test_import_04_08() {
805        Persy::create("import_from_04_08.persy").expect("creation works fine");
806        let p = &Persy::open("import_from_04_08.persy", Config::new()).expect("open fine");
807        let mut f = File::open("fixtures/0.4_0.8_all.json").expect("open correctly the file");
808        let mut data = String::new();
809
810        f.read_to_string(&mut data).expect("read all fine");
811        import_json(p, &mut Cursor::new(data)).unwrap();
812        for (_, content) in p.scan("test").unwrap() {
813            assert_eq!("test".to_string().as_bytes().to_vec(), content);
814        }
815        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
816        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
817        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
818        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
819        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
820        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
821        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
822        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
823        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
824        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
825        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
826        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
827        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
828        let bv = ByteVec::new(vec![20, 10]);
829        let bv1 = ByteVec::new(vec![10, 20]);
830        check_key_value(p, "test_bytevec", bv, bv1);
831        assert_eq!(
832            1,
833            p.range::<PersyId, PersyId, _>("test_p", ..)
834                .unwrap()
835                .into_iter()
836                .count()
837        );
838        fs::remove_file("import_from_04_08.persy").unwrap();
839    }
840
841    #[test]
842    pub fn test_import_05_09() {
843        Persy::create("import_from_05_09.persy").expect("creation works fine");
844        let p = &Persy::open("import_from_05_09.persy", Config::new()).expect("open fine");
845        let mut f = File::open("fixtures/0.5_0.9_all.json").expect("open correctly the file");
846        let mut data = String::new();
847
848        f.read_to_string(&mut data).expect("read all fine");
849        import_json(p, &mut Cursor::new(data)).unwrap();
850        for (_, content) in p.scan("test").unwrap() {
851            assert_eq!("test".to_string().as_bytes().to_vec(), content);
852        }
853        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
854        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
855        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
856        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
857        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
858        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
859        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
860        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
861        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
862        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
863        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
864        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
865        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
866        let bv = ByteVec::new(vec![20, 10]);
867        let bv1 = ByteVec::new(vec![10, 20]);
868        check_key_value(p, "test_bytevec", bv, bv1);
869        assert_eq!(
870            1,
871            p.range::<PersyId, PersyId, _>("test_p", ..)
872                .unwrap()
873                .into_iter()
874                .count()
875        );
876        fs::remove_file("import_from_05_09.persy").unwrap();
877    }
878
879    #[test]
880    pub fn test_import_06_10() {
881        Persy::create("import_from_06_10.persy").expect("creation works fine");
882        let p = &Persy::open("import_from_06_10.persy", Config::new()).expect("open fine");
883        let mut f = File::open("fixtures/0.6_0.10_all.json").expect("open correctly the file");
884        let mut data = String::new();
885
886        f.read_to_string(&mut data).expect("read all fine");
887        import_json(p, &mut Cursor::new(data)).unwrap();
888        for (_, content) in p.scan("test").unwrap() {
889            assert_eq!("test".to_string().as_bytes().to_vec(), content);
890        }
891        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
892        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
893        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
894        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
895        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
896        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
897        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
898        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
899        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
900        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
901        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
902        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
903        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
904        let bv = ByteVec::new(vec![20, 10]);
905        let bv1 = ByteVec::new(vec![10, 20]);
906        check_key_value(p, "test_bytevec", bv, bv1);
907        assert_eq!(
908            1,
909            p.range::<PersyId, PersyId, _>("test_p", ..)
910                .unwrap()
911                .into_iter()
912                .count()
913        );
914        fs::remove_file("import_from_06_10.persy").unwrap();
915    }
916
917    #[test]
918    pub fn test_import_07_11() {
919        Persy::create("import_from_07_11.persy").expect("creation works fine");
920        let p = &Persy::open("import_from_07_11.persy", Config::new()).expect("open fine");
921        let mut f = File::open("fixtures/0.7_0.11_all.json").expect("open correctly the file");
922        let mut data = String::new();
923
924        f.read_to_string(&mut data).expect("read all fine");
925        import_json(p, &mut Cursor::new(data)).unwrap();
926        for (_, content) in p.scan("test").unwrap() {
927            assert_eq!("test".to_string().as_bytes().to_vec(), content);
928        }
929        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
930        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
931        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
932        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
933        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
934        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
935        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
936        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
937        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
938        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
939        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
940        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
941        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
942        let bv = ByteVec::new(vec![20, 10]);
943        let bv1 = ByteVec::new(vec![10, 20]);
944        check_key_value(p, "test_bytevec", bv, bv1);
945        assert_eq!(
946            1,
947            p.range::<PersyId, PersyId, _>("test_p", ..)
948                .unwrap()
949                .into_iter()
950                .count()
951        );
952        fs::remove_file("import_from_07_11.persy").unwrap();
953    }
954
955    #[test]
956    pub fn test_import_08_100() {
957        Persy::create("import_from_08_100.persy").expect("creation works fine");
958        let p = &Persy::open("import_from_08_100.persy", Config::new()).expect("open fine");
959        let mut f = File::open("fixtures/0.8_1.0_all.json").expect("open correctly the file");
960        let mut data = String::new();
961
962        f.read_to_string(&mut data).expect("read all fine");
963        import_json(p, &mut Cursor::new(data)).unwrap();
964        for (_, content) in p.scan("test").unwrap() {
965            assert_eq!("test".to_string().as_bytes().to_vec(), content);
966        }
967        check_key_value(p, "test_u8", 10 as u8, 10 as u8);
968        check_key_value(p, "test_u16", 10 as u16, 10 as u16);
969        check_key_value(p, "test_u32", 10 as u32, 10 as u32);
970        check_key_value(p, "test_u64", 10 as u64, 10 as u64);
971        check_key_value(p, "test_u128", 10 as u128, 10 as u128);
972        check_key_value(p, "test_i8", 10 as i8, 10 as i8);
973        check_key_value(p, "test_i16", 10 as i16, 10 as i16);
974        check_key_value(p, "test_i32", 10 as i32, 10 as i32);
975        check_key_value(p, "test_i64", 10 as i64, 10 as i64);
976        check_key_value(p, "test_i128", 10 as i128, 10 as i128);
977        check_key_value(p, "test_f32", 10 as f32, 10 as f32);
978        check_key_value(p, "test_f64", 10 as f64, 10 as f64);
979        check_key_value(p, "test_string", "one".to_string(), "two".to_string());
980        let bv = ByteVec::new(vec![20, 10]);
981        let bv1 = ByteVec::new(vec![10, 20]);
982        check_key_value(p, "test_bytevec", bv, bv1);
983        assert_eq!(
984            1,
985            p.range::<PersyId, PersyId, _>("test_p", ..)
986                .unwrap()
987                .into_iter()
988                .count()
989        );
990        fs::remove_file("import_from_08_100.persy").unwrap();
991    }
992}