| 1 | use crate::block::{ItemContent, Prelim}; |
| 2 | use crate::branch::{Branch, BranchPtr}; |
| 3 | use crate::types::text::DeltaPrelim; |
| 4 | use crate::types::xml::XmlDeltaPrelim; |
| 5 | use crate::types::TypeRef; |
| 6 | use crate::{ |
| 7 | Any, ArrayPrelim, Doc, MapPrelim, Out, TransactionMut, XmlElementPrelim, XmlFragmentPrelim, |
| 8 | }; |
| 9 | |
| 10 | /// A wrapper around [Out] type that enables it to be used as a type to be inserted into |
| 11 | /// shared collections. If [In] contains a shared type, it will be inserted as a deep |
| 12 | /// copy of the original type: therefore none of the changes applied to the original type will |
| 13 | /// affect the deep copy. |
| 14 | #[derive(Debug, Clone, PartialEq)] |
| 15 | pub enum In { |
| 16 | Any(Any), |
| 17 | Text(DeltaPrelim), |
| 18 | Array(ArrayPrelim), |
| 19 | Map(MapPrelim), |
| 20 | XmlElement(XmlElementPrelim), |
| 21 | XmlFragment(XmlFragmentPrelim), |
| 22 | XmlText(XmlDeltaPrelim), |
| 23 | Doc(Doc), |
| 24 | #[cfg(feature = "weak")] |
| 25 | WeakLink(crate::types::weak::WeakPrelim<BranchPtr>), |
| 26 | } |
| 27 | |
| 28 | impl Prelim for In { |
| 29 | type Return = Out; |
| 30 | |
| 31 | fn into_content(self, _txn: &mut TransactionMut) -> (ItemContent, Option<Self>) { |
| 32 | match self { |
| 33 | In::Any(any) => (ItemContent::Any(vec![any]), None), |
| 34 | other => { |
| 35 | let type_ref = match &other { |
| 36 | In::Text(_) => TypeRef::Text, |
| 37 | In::Array(_) => TypeRef::Array, |
| 38 | In::Map(_) => TypeRef::Map, |
| 39 | In::XmlElement(v) => TypeRef::XmlElement(v.tag.clone()), |
| 40 | In::XmlFragment(_) => TypeRef::XmlFragment, |
| 41 | In::XmlText(_) => TypeRef::XmlText, |
| 42 | In::Doc(_) => TypeRef::SubDoc, |
| 43 | #[cfg(feature = "weak")] |
| 44 | In::WeakLink(v) => TypeRef::WeakLink(v.source().clone()), |
| 45 | _ => unreachable!(), |
| 46 | }; |
| 47 | (ItemContent::Type(Branch::new(type_ref)), Some(other)) |
| 48 | } |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | fn integrate(self, txn: &mut TransactionMut, inner_ref: BranchPtr) { |
| 53 | match self { |
| 54 | In::Text(prelim) => prelim.integrate(txn, inner_ref), |
| 55 | In::Array(prelim) => prelim.integrate(txn, inner_ref), |
| 56 | In::Map(prelim) => prelim.integrate(txn, inner_ref), |
| 57 | In::XmlElement(prelim) => prelim.integrate(txn, inner_ref), |
| 58 | In::XmlFragment(prelim) => prelim.integrate(txn, inner_ref), |
| 59 | In::XmlText(prelim) => prelim.integrate(txn, inner_ref), |
| 60 | In::Doc(prelim) => prelim.integrate(txn, inner_ref), |
| 61 | #[cfg(feature = "weak")] |
| 62 | In::WeakLink(prelim) => prelim.integrate(txn, inner_ref), |
| 63 | _ => { /* do nothing */ } |
| 64 | } |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | impl From<Any> for In { |
| 69 | #[inline] |
| 70 | fn from(value: Any) -> Self { |
| 71 | In::Any(value) |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | macro_rules! impl_from_any { |
| 76 | ($t:ty) => { |
| 77 | impl From<$t> for In { |
| 78 | #[inline] |
| 79 | fn from(value: $t) -> Self { |
| 80 | In::Any(Any::from(value)) |
| 81 | } |
| 82 | } |
| 83 | }; |
| 84 | } |
| 85 | |
| 86 | impl_from_any!(bool); |
| 87 | impl_from_any!(i16); |
| 88 | impl_from_any!(i32); |
| 89 | impl_from_any!(i64); |
| 90 | impl_from_any!(u16); |
| 91 | impl_from_any!(u32); |
| 92 | impl_from_any!(f32); |
| 93 | impl_from_any!(f64); |
| 94 | impl_from_any!(String); |
| 95 | impl_from_any!(std::sync::Arc<str>); |
| 96 | impl_from_any!(&str); |
| 97 | impl_from_any!(Vec<u8>); |
| 98 | impl_from_any!(&[u8]); |
| 99 | |