structsy/
record.rs

1//! Raw access structures
2//!
3use crate::{
4    desc::{
5        Description, EnumDescription, FieldDescription, SimpleValueType, StructDescription, SupportedType, ValueType,
6        VariantDescription,
7    },
8    error::SRes,
9    internal::PersistentEmbedded,
10    StructsyError,
11};
12use persy::{IndexType, PersyId, Transaction, ValueMode};
13use std::io::{Read, Write};
14/// Builder to generate a struct record that then can be persisted
15pub struct StructBuilder {
16    desc: StructDescription,
17    fields: Vec<FieldValue>,
18}
19
20impl StructBuilder {
21    pub fn new(desc: Description) -> SRes<Self> {
22        let desc = match desc {
23            Description::Struct(desc) => desc,
24            _ => return Err(StructsyError::TypeError("Expected a struct definition".to_owned())),
25        };
26        Ok(Self {
27            desc,
28            fields: Vec::new(),
29        })
30    }
31    pub fn add_field<T: SupportedType>(mut self, name: &str, value: T) -> SRes<Self> {
32        let found = self.desc.fields().find(|field| field.name == name);
33        if let Some(field) = found {
34            if field.field_type == T::resolve() {
35                let fv = FieldValue {
36                    position: field.position(),
37                    name: field.name().to_owned(),
38                    value_type: field.field_type().clone(),
39                    value: value.new()?,
40                    indexed: field.indexed().clone(),
41                };
42                self.fields.push(fv);
43                Ok(self)
44            } else {
45                Err(StructsyError::ValueChangeError(format!(
46                    "value type:'{:?}' do not match expected type:'{:?}'",
47                    T::resolve(),
48                    field.field_type
49                )))
50            }
51        } else {
52            Err(StructsyError::ValueChangeError(format!(
53                "field with name '{}' not found",
54                name
55            )))
56        }
57    }
58
59    pub fn finish(self) -> SRes<Record> {
60        if self.desc.fields().count() != self.fields.len() {
61            return Err(StructsyError::ValueChangeError("Missing fields".to_owned()));
62        }
63        Ok(Record::Struct(StructRecord {
64            struct_name: self.desc.get_name(),
65            fields: self.fields,
66        }))
67    }
68}
69/// Builder to generate an enum record that then can be persisted
70pub struct EnumBuilder {
71    desc: EnumDescription,
72    variant: Option<Box<VariantValue>>,
73}
74impl EnumBuilder {
75    pub fn new(desc: Description) -> SRes<Self> {
76        let desc = match desc {
77            Description::Enum(desc) => desc,
78            _ => return Err(StructsyError::TypeError("Expected a enum definition".to_owned())),
79        };
80        Ok(Self { desc, variant: None })
81    }
82
83    pub fn set_value_variant<T: SupportedType>(&mut self, name: &str, val: T) -> SRes<()> {
84        if let Some(v) = self.desc.variants().find(|v| v.name == name) {
85            if v.value_type() == &Some(T::resolve()) {
86                self.variant = Some(Box::new(VariantValue::new(v, Some(val.new()?))));
87                Ok(())
88            } else {
89                Err(StructsyError::ValueChangeError(format!(
90                    "value type:'{:?}' do not match expected type:'{:?}'",
91                    T::resolve(),
92                    v.value_type()
93                )))
94            }
95        } else {
96            Err(StructsyError::ValueChangeError(format!(
97                "variant with name '{}' not found",
98                name
99            )))
100        }
101    }
102
103    pub fn set_simple_variant(&mut self, name: &str) -> SRes<()> {
104        if let Some(v) = self.desc.variants().find(|v| v.name == name) {
105            if v.value_type() == &None {
106                self.variant = Some(Box::new(VariantValue::new(v, None)));
107                Ok(())
108            } else {
109                Err(StructsyError::ValueChangeError(format!(
110                    "value type:'None' do not match expected type:'{:?}'",
111                    v.value_type()
112                )))
113            }
114        } else {
115            Err(StructsyError::ValueChangeError(format!(
116                "variant with name '{}' not found",
117                name
118            )))
119        }
120    }
121
122    pub fn finish(self) -> SRes<Record> {
123        if self.variant.is_none() {
124            return Err(StructsyError::ValueChangeError(
125                "Requited to set the variant".to_owned(),
126            ));
127        }
128        Ok(Record::Enum(EnumRecord {
129            name: self.desc.get_name(),
130            variant: self.variant.unwrap(),
131            desc: self.desc,
132        }))
133    }
134}
135
136/// Type Generic structsy record, that can be used to extract data
137/// from a structsy database without the original source code, helpful
138/// also for debug purposes.
139#[derive(PartialEq, Clone, Debug)]
140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
141pub enum Record {
142    Struct(StructRecord),
143    Enum(EnumRecord),
144}
145impl Record {
146    pub fn read(read: &mut dyn Read, desc: &Description) -> SRes<Record> {
147        Ok(match desc {
148            Description::Struct(s) => Record::Struct(StructRecord::read(read, s)?),
149            Description::Enum(e) => Record::Enum(EnumRecord::read(read, e)?),
150        })
151    }
152
153    pub fn write(&self, write: &mut dyn Write, desc: &Description) -> SRes<()> {
154        match self {
155            Record::Struct(s) => {
156                let sd = match desc {
157                    Description::Struct(ed) => ed,
158                    _ => panic!("description does not match the value"),
159                };
160                s.write(write, sd)?;
161            }
162            Record::Enum(e) => {
163                let ed = match desc {
164                    Description::Enum(ed) => ed,
165                    _ => panic!("description does not match the value"),
166                };
167                e.write(write, ed)?;
168            }
169        }
170        Ok(())
171    }
172
173    pub(crate) fn put_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
174        match self {
175            Record::Struct(s) => {
176                s.put_indexes(tx, id)?;
177            }
178            Record::Enum(e) => {
179                e.put_indexes(tx, id)?;
180            }
181        }
182        Ok(())
183    }
184
185    pub(crate) fn remove_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
186        match self {
187            Record::Struct(s) => {
188                s.remove_indexes(tx, id)?;
189            }
190            Record::Enum(e) => {
191                e.remove_indexes(tx, id)?;
192            }
193        }
194        Ok(())
195    }
196
197    pub fn type_name(&self) -> &str {
198        match self {
199            Record::Struct(s) => s.type_name(),
200            Record::Enum(e) => e.type_name(),
201        }
202    }
203}
204
205/// Struct data used for extraction and debug
206#[derive(PartialEq, Clone, Debug)]
207#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
208pub struct StructRecord {
209    pub(crate) struct_name: String,
210    pub(crate) fields: Vec<FieldValue>,
211}
212impl StructRecord {
213    fn read(read: &mut dyn Read, desc: &StructDescription) -> SRes<StructRecord> {
214        let mut fields = Vec::new();
215        for field in desc.fields() {
216            fields.push(FieldValue::read(read, field)?);
217        }
218        Ok(StructRecord {
219            struct_name: desc.get_name(),
220            fields,
221        })
222    }
223
224    fn write(&self, write: &mut dyn Write, desc: &StructDescription) -> SRes<()> {
225        for field in &self.fields {
226            let fd = if let Some(fd) = desc.get_field(field.name()) {
227                fd
228            } else {
229                panic!("value do not match the definition");
230            };
231
232            field.write(write, fd)?;
233        }
234        Ok(())
235    }
236
237    pub fn type_name(&self) -> &str {
238        &self.struct_name
239    }
240    pub fn fields(&self) -> impl Iterator<Item = &FieldValue> {
241        self.fields.iter()
242    }
243    pub fn field(&self, name: &str) -> Option<&FieldValue> {
244        for field in &self.fields {
245            if field.name == name {
246                return Some(field);
247            }
248        }
249        None
250    }
251
252    pub fn set_field<T: SupportedType>(&mut self, name: &str, value: T) -> SRes<()> {
253        if let Some(field) = &mut self.fields.iter_mut().find(|field| field.name == name) {
254            if field.value_type == T::resolve() {
255                field.value = value.new()?;
256                Ok(())
257            } else {
258                Err(StructsyError::ValueChangeError(format!(
259                    "value type:'{:?}' do not match expected type:'{:?}'",
260                    T::resolve(),
261                    field.value_type
262                )))
263            }
264        } else {
265            Err(StructsyError::ValueChangeError(format!(
266                "field with name '{}' not found",
267                name
268            )))
269        }
270    }
271
272    pub(crate) fn put_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
273        for field in &self.fields {
274            field.put_indexes(tx, self.type_name(), id)?;
275        }
276        Ok(())
277    }
278    pub(crate) fn remove_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
279        for field in &self.fields {
280            field.remove_indexes(tx, self.type_name(), id)?;
281        }
282        Ok(())
283    }
284}
285
286/// Enum data used for extraction and debug
287#[derive(PartialEq, Clone, Debug)]
288#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
289pub struct EnumRecord {
290    pub(crate) name: String,
291    pub(crate) variant: Box<VariantValue>,
292    pub(crate) desc: EnumDescription,
293}
294impl EnumRecord {
295    fn read(read: &mut dyn Read, desc: &EnumDescription) -> SRes<EnumRecord> {
296        let pos = u32::read(read)?;
297        let value = VariantValue::read(read, desc.variant(pos as usize))?;
298        Ok(EnumRecord {
299            name: desc.get_name(),
300            variant: Box::new(value),
301            desc: desc.clone(),
302        })
303    }
304
305    fn write(&self, write: &mut dyn Write, desc: &EnumDescription) -> SRes<()> {
306        u32::write(&self.variant.position, write)?;
307        self.variant
308            .write(write, desc.variant(self.variant.position as usize))?;
309        Ok(())
310    }
311
312    pub fn variant(&self) -> &VariantValue {
313        &self.variant
314    }
315
316    pub fn set_value_variant<T: SupportedType>(&mut self, name: &str, val: T) -> SRes<()> {
317        if let Some(v) = self.desc.variants().find(|v| v.name == name) {
318            if v.value_type() == &Some(T::resolve()) {
319                self.variant = Box::new(VariantValue::new(v, Some(val.new()?)));
320                Ok(())
321            } else {
322                Err(StructsyError::ValueChangeError(format!(
323                    "value type:'{:?}' do not match expected type:'{:?}'",
324                    T::resolve(),
325                    v.value_type()
326                )))
327            }
328        } else {
329            Err(StructsyError::ValueChangeError(format!(
330                "variant with name '{}' not found",
331                name
332            )))
333        }
334    }
335
336    pub fn set_simple_variant(&mut self, name: &str) -> SRes<()> {
337        if let Some(v) = self.desc.variants().find(|v| v.name == name) {
338            if v.value_type() == &None {
339                self.variant = Box::new(VariantValue::new(v, None));
340                Ok(())
341            } else {
342                Err(StructsyError::ValueChangeError(format!(
343                    "value type:'None' do not match expected type:'{:?}'",
344                    v.value_type()
345                )))
346            }
347        } else {
348            Err(StructsyError::ValueChangeError(format!(
349                "variant with name '{}' not found",
350                name
351            )))
352        }
353    }
354
355    pub fn type_name(&self) -> &str {
356        &self.name
357    }
358    pub(crate) fn put_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
359        self.variant.put_indexes(tx, id)
360    }
361    pub(crate) fn remove_indexes(&self, tx: &mut persy::Transaction, id: &PersyId) -> SRes<()> {
362        self.variant.remove_indexes(tx, id)
363    }
364}
365
366/// Enum value for extraction and debug
367#[derive(PartialEq, Clone, Debug)]
368#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
369pub struct VariantValue {
370    pub(crate) position: u32,
371    pub(crate) name: String,
372    pub(crate) value: Option<Value>,
373}
374impl VariantValue {
375    fn new(desc: &VariantDescription, value: Option<Value>) -> VariantValue {
376        VariantValue {
377            position: desc.position(),
378            name: desc.name().to_owned(),
379            value,
380        }
381    }
382    fn read(read: &mut dyn Read, desc: &VariantDescription) -> SRes<VariantValue> {
383        let value = if let Some(value_type) = desc.value_type() {
384            Some(Value::read(read, value_type)?)
385        } else {
386            None
387        };
388        Ok(Self::new(desc, value))
389    }
390    fn write(&self, write: &mut dyn Write, desc: &VariantDescription) -> SRes<()> {
391        if let Some(val) = &self.value {
392            val.write(write, desc.value_type().as_ref().expect("value and desc match"))?;
393        }
394        Ok(())
395    }
396    pub fn value(&self) -> &Option<Value> {
397        &self.value
398    }
399    pub fn name(&self) -> &str {
400        &self.name
401    }
402    pub(crate) fn put_indexes(&self, _tx: &mut persy::Transaction, _id: &PersyId) -> SRes<()> {
403        Ok(())
404    }
405    pub(crate) fn remove_indexes(&self, _tx: &mut persy::Transaction, _id: &PersyId) -> SRes<()> {
406        Ok(())
407    }
408}
409
410/// Field data used for extraction and debug
411#[derive(PartialEq, Clone, Debug)]
412#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
413pub struct FieldValue {
414    pub(crate) position: u32,
415    pub(crate) name: String,
416    pub(crate) value: Value,
417    pub(crate) value_type: ValueType,
418    #[cfg_attr(
419        feature = "serde",
420        serde(
421            serialize_with = "crate::desc::value_mode_serialize",
422            deserialize_with = "crate::desc::value_mode_deserialize"
423        )
424    )]
425    pub(crate) indexed: Option<ValueMode>,
426}
427impl FieldValue {
428    fn read(read: &mut dyn Read, field: &FieldDescription) -> SRes<FieldValue> {
429        Ok(FieldValue {
430            position: field.position(),
431            name: field.name().to_owned(),
432            value: Value::read(read, field.field_type())?,
433            value_type: field.field_type().clone(),
434            indexed: field.indexed.clone(),
435        })
436    }
437    fn write(&self, write: &mut dyn Write, field: &FieldDescription) -> SRes<()> {
438        self.value.write(write, &field.field_type)
439    }
440    pub fn position(&self) -> u32 {
441        self.position
442    }
443    pub fn name(&self) -> &str {
444        &self.name
445    }
446    pub fn value(&self) -> &Value {
447        &self.value
448    }
449    pub(crate) fn put_indexes(&self, tx: &mut persy::Transaction, type_name: &str, id: &PersyId) -> SRes<()> {
450        if self.indexed.is_some() {
451            self.value.put_index(tx, type_name, &self.name, id)?;
452        }
453        Ok(())
454    }
455    pub(crate) fn remove_indexes(&self, tx: &mut persy::Transaction, type_name: &str, id: &PersyId) -> SRes<()> {
456        if self.indexed.is_some() {
457            self.value.remove_index(tx, type_name, &self.name, id)?;
458        }
459        Ok(())
460    }
461}
462
463/// A possible value of enum variant or struct field, debug and extraction structure
464#[derive(PartialEq, Clone, Debug)]
465#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
466pub enum Value {
467    Value(SimpleValue),
468    Option(Option<SimpleValue>),
469    Array(Vec<SimpleValue>),
470    OptionArray(Option<Vec<SimpleValue>>),
471}
472impl Value {
473    pub fn new<T: SupportedType>(value: T) -> SRes<Value> {
474        value.new()
475    }
476
477    fn read(read: &mut dyn Read, field_type: &ValueType) -> SRes<Value> {
478        Ok(match field_type {
479            ValueType::Value(t) => Value::Value(SimpleValue::read(read, t)?),
480            ValueType::Option(t) => {
481                if u8::read(read)? == 1 {
482                    Value::Option(Some(SimpleValue::read(read, t)?))
483                } else {
484                    Value::Option(None)
485                }
486            }
487            ValueType::Array(t) => {
488                let len = u32::read(read)?;
489                let mut v = Vec::new();
490                for _ in 0..len {
491                    v.push(SimpleValue::read(read, t)?);
492                }
493                Value::Array(v)
494            }
495            ValueType::OptionArray(t) => {
496                if u8::read(read)? == 1 {
497                    let len = u32::read(read)?;
498                    let mut v = Vec::new();
499                    for _ in 0..len {
500                        v.push(SimpleValue::read(read, t)?);
501                    }
502                    Value::OptionArray(Some(v))
503                } else {
504                    Value::OptionArray(None)
505                }
506            }
507        })
508    }
509
510    fn write(&self, write: &mut dyn Write, field_type: &ValueType) -> SRes<()> {
511        match self {
512            Value::Value(v) => {
513                let vt = match field_type {
514                    ValueType::Value(vt) => vt,
515                    _ => panic!("desc do not match field type"),
516                };
517                v.write(write, vt)?;
518            }
519            Value::Option(v) => {
520                let vt = match field_type {
521                    ValueType::Option(vt) => vt,
522                    _ => panic!("desc do not match field type"),
523                };
524                if let Some(sv) = v {
525                    u8::write(&1, write)?;
526                    sv.write(write, vt)?;
527                } else {
528                    u8::write(&0, write)?;
529                }
530            }
531            Value::Array(v) => {
532                let vt = match field_type {
533                    ValueType::Array(vt) => vt,
534                    _ => panic!("desc do not match field type"),
535                };
536                u32::write(&(v.len() as u32), write)?;
537                for sv in v {
538                    sv.write(write, vt)?;
539                }
540            }
541            Value::OptionArray(v) => {
542                let vt = match field_type {
543                    ValueType::OptionArray(vt) => vt,
544                    _ => panic!("desc do not match field type"),
545                };
546                if let Some(sv) = v {
547                    u8::write(&1, write)?;
548                    u32::write(&(sv.len() as u32), write)?;
549                    for ssv in sv {
550                        ssv.write(write, vt)?;
551                    }
552                } else {
553                    u8::write(&0, write)?;
554                }
555            }
556        }
557        Ok(())
558    }
559
560    pub(crate) fn put_index(&self, tx: &mut persy::Transaction, type_name: &str, name: &str, id: &PersyId) -> SRes<()> {
561        match self {
562            Value::Value(v) => {
563                v.put_index(tx, type_name, name, id)?;
564            }
565            Value::Option(v) => {
566                if let Some(sv) = v {
567                    sv.put_index(tx, type_name, name, id)?;
568                }
569            }
570            Value::Array(v) => {
571                for sv in v {
572                    sv.put_index(tx, type_name, name, id)?;
573                }
574            }
575            Value::OptionArray(v) => {
576                if let Some(sv) = v {
577                    for ssv in sv {
578                        ssv.put_index(tx, type_name, name, id)?;
579                    }
580                }
581            }
582        }
583        Ok(())
584    }
585    pub(crate) fn remove_index(
586        &self,
587        tx: &mut persy::Transaction,
588        type_name: &str,
589        name: &str,
590        id: &PersyId,
591    ) -> SRes<()> {
592        match self {
593            Value::Value(v) => {
594                v.remove_index(tx, type_name, name, id)?;
595            }
596            Value::Option(v) => {
597                if let Some(sv) = v {
598                    sv.remove_index(tx, type_name, name, id)?;
599                }
600            }
601            Value::Array(v) => {
602                for sv in v {
603                    sv.remove_index(tx, type_name, name, id)?;
604                }
605            }
606            Value::OptionArray(v) => {
607                if let Some(sv) = v {
608                    for ssv in sv {
609                        ssv.remove_index(tx, type_name, name, id)?;
610                    }
611                }
612            }
613        }
614        Ok(())
615    }
616}
617
618/// A possible simple value supported by structsy, debug and extraction structure
619#[derive(PartialEq, Clone, Debug)]
620#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
621pub enum SimpleValue {
622    U8(u8),
623    U16(u16),
624    U32(u32),
625    U64(u64),
626    U128(u128),
627    I8(i8),
628    I16(i16),
629    I32(i32),
630    I64(i64),
631    I128(i128),
632    F32(f32),
633    F64(f64),
634    Bool(bool),
635    String(String),
636    Ref(String),
637    Embedded(Record),
638}
639
640impl SimpleValue {
641    fn read(read: &mut dyn Read, value_type: &SimpleValueType) -> SRes<SimpleValue> {
642        use crate::desc::SimpleValueType::*;
643        Ok(match value_type {
644            U8 => SimpleValue::U8(u8::read(read)?),
645            U16 => SimpleValue::U16(u16::read(read)?),
646            U32 => SimpleValue::U32(u32::read(read)?),
647            U64 => SimpleValue::U64(u64::read(read)?),
648            U128 => SimpleValue::U128(u128::read(read)?),
649            I8 => SimpleValue::I8(i8::read(read)?),
650            I16 => SimpleValue::I16(i16::read(read)?),
651            I32 => SimpleValue::I32(i32::read(read)?),
652            I64 => SimpleValue::I64(i64::read(read)?),
653            I128 => SimpleValue::I128(i128::read(read)?),
654            F32 => SimpleValue::F32(f32::read(read)?),
655            F64 => SimpleValue::F64(f64::read(read)?),
656            Bool => SimpleValue::Bool(bool::read(read)?),
657            String => SimpleValue::String(std::string::String::read(read)?),
658            Ref(t) => SimpleValue::Ref(format!("{}@{}", t, std::string::String::read(read)?)),
659            Embedded(desc) => SimpleValue::Embedded(Record::read(read, desc)?),
660        })
661    }
662    fn write(&self, write: &mut dyn Write, value_type: &SimpleValueType) -> SRes<()> {
663        match self {
664            SimpleValue::U8(v) => u8::write(v, write)?,
665            SimpleValue::U16(v) => u16::write(v, write)?,
666            SimpleValue::U32(v) => u32::write(v, write)?,
667            SimpleValue::U64(v) => u64::write(v, write)?,
668            SimpleValue::U128(v) => u128::write(v, write)?,
669            SimpleValue::I8(v) => i8::write(v, write)?,
670            SimpleValue::I16(v) => i16::write(v, write)?,
671            SimpleValue::I32(v) => i32::write(v, write)?,
672            SimpleValue::I64(v) => i64::write(v, write)?,
673            SimpleValue::I128(v) => i128::write(v, write)?,
674            SimpleValue::F32(v) => f32::write(v, write)?,
675            SimpleValue::F64(v) => f64::write(v, write)?,
676            SimpleValue::Bool(v) => bool::write(v, write)?,
677            SimpleValue::String(v) => std::string::String::write(v, write)?,
678            SimpleValue::Ref(v) => {
679                let values = v.split('@').collect::<Vec<_>>();
680                if values.len() < 2 {
681                    panic!("wrong value");
682                }
683                std::string::String::write(&values[1].to_owned(), write)?;
684            }
685            SimpleValue::Embedded(v) => {
686                let desc = match value_type {
687                    SimpleValueType::Embedded(desc) => desc,
688                    _ => panic!("type do not mach desc"),
689                };
690                v.write(write, desc)?;
691            }
692        }
693        Ok(())
694    }
695
696    pub(crate) fn put_index(&self, tx: &mut persy::Transaction, type_name: &str, name: &str, id: &PersyId) -> SRes<()> {
697        match self {
698            SimpleValue::U8(v) => put_index(tx, type_name, name, v, id)?,
699            SimpleValue::U16(v) => put_index(tx, type_name, name, v, id)?,
700            SimpleValue::U32(v) => put_index(tx, type_name, name, v, id)?,
701            SimpleValue::U64(v) => put_index(tx, type_name, name, v, id)?,
702            SimpleValue::U128(v) => put_index(tx, type_name, name, v, id)?,
703            SimpleValue::I8(v) => put_index(tx, type_name, name, v, id)?,
704            SimpleValue::I16(v) => put_index(tx, type_name, name, v, id)?,
705            SimpleValue::I32(v) => put_index(tx, type_name, name, v, id)?,
706            SimpleValue::I64(v) => put_index(tx, type_name, name, v, id)?,
707            SimpleValue::I128(v) => put_index(tx, type_name, name, v, id)?,
708            SimpleValue::F32(v) => put_index(tx, type_name, name, v, id)?,
709            SimpleValue::F64(v) => put_index(tx, type_name, name, v, id)?,
710            SimpleValue::Bool(_v) => {}
711            SimpleValue::String(v) => put_index(tx, type_name, name, &v.clone(), id)?,
712            SimpleValue::Ref(v) => {
713                let values = v.split('@').collect::<Vec<_>>();
714                if values.len() < 2 {
715                    panic!("wrong value");
716                }
717                put_index(tx, type_name, name, &values[1].parse::<PersyId>()?, id)?;
718            }
719            SimpleValue::Embedded(_v) => {}
720        }
721        Ok(())
722    }
723
724    pub(crate) fn remove_index(
725        &self,
726        tx: &mut persy::Transaction,
727        type_name: &str,
728        name: &str,
729        id: &PersyId,
730    ) -> SRes<()> {
731        match self {
732            SimpleValue::U8(v) => remove_index(tx, type_name, name, v, id)?,
733            SimpleValue::U16(v) => remove_index(tx, type_name, name, v, id)?,
734            SimpleValue::U32(v) => remove_index(tx, type_name, name, v, id)?,
735            SimpleValue::U64(v) => remove_index(tx, type_name, name, v, id)?,
736            SimpleValue::U128(v) => remove_index(tx, type_name, name, v, id)?,
737            SimpleValue::I8(v) => remove_index(tx, type_name, name, v, id)?,
738            SimpleValue::I16(v) => remove_index(tx, type_name, name, v, id)?,
739            SimpleValue::I32(v) => remove_index(tx, type_name, name, v, id)?,
740            SimpleValue::I64(v) => remove_index(tx, type_name, name, v, id)?,
741            SimpleValue::I128(v) => remove_index(tx, type_name, name, v, id)?,
742            SimpleValue::F32(v) => remove_index(tx, type_name, name, v, id)?,
743            SimpleValue::F64(v) => remove_index(tx, type_name, name, v, id)?,
744            SimpleValue::Bool(_v) => {}
745            SimpleValue::String(v) => remove_index(tx, type_name, name, &v.clone(), id)?,
746            SimpleValue::Ref(v) => {
747                let values = v.split('@').collect::<Vec<_>>();
748                if values.len() < 2 {
749                    panic!("wrong value");
750                }
751                remove_index(tx, type_name, name, &values[1].parse::<PersyId>()?, id)?;
752            }
753            SimpleValue::Embedded(_v) => {}
754        }
755        Ok(())
756    }
757}
758
759fn put_index<T: IndexType>(tx: &mut Transaction, type_name: &str, name: &str, k: &T, id: &PersyId) -> SRes<()> {
760    tx.put::<T, PersyId>(&format!("{}.{}", type_name, name), k.clone(), id.clone())?;
761    Ok(())
762}
763
764fn remove_index<T: IndexType>(tx: &mut Transaction, type_name: &str, name: &str, k: &T, id: &PersyId) -> SRes<()> {
765    tx.remove::<T, PersyId>(&format!("{}.{}", type_name, name), k.clone(), Some(id.clone()))?;
766    Ok(())
767}