1use smallvec::SmallVec;
2use im::OrdMap;
3
4use crate::collection::nitrite_id::NitriteId;
5use crate::common::{ReadExecutor, Value, DOC_ID, DOC_MODIFIED, DOC_REVISION, DOC_SOURCE, RESERVED_FIELDS};
6use crate::errors::{ErrorKind, NitriteError, NitriteResult};
7use crate::FIELD_SEPARATOR;
8use itertools::Itertools;
9use std::borrow::Cow;
10use std::collections::{BTreeMap, BTreeSet};
11use std::fmt::{Debug, Display};
12
13type FieldVec = SmallVec<[String; 8]>;
14
15#[derive(Clone, Eq, PartialEq, Hash, Default, Ord, PartialOrd, serde::Deserialize, serde::Serialize)]
43pub struct Document {
44 data: OrdMap<String, Value>,
46}
47
48impl Document {
49 pub fn new() -> Self {
59 Document {
60 data: OrdMap::new(),
61 }
62 }
63
64 pub fn is_empty(&self) -> bool {
76 self.data.is_empty()
77 }
78
79 pub fn put<'a, T: Into<Value>>(&mut self, key: impl Into<Cow<'a, str>>, value: T) -> NitriteResult<()> {
122 let key = key.into();
123 if key.is_empty() {
125 log::error!("Document does not support empty key");
126 return Err(NitriteError::new(
127 "Document does not support empty key",
128 ErrorKind::InvalidOperation,
129 ));
130 }
131
132 let value = value.into();
133
134 if key == DOC_ID && !value.is_nitrite_id() {
136 log::error!("Document id is an auto generated field and cannot be set manually");
137 return Err(NitriteError::new(
138 "Document id is an auto generated field and cannot be set manually",
139 ErrorKind::InvalidOperation,
140 ));
141 }
142
143 if FIELD_SEPARATOR.read_with(|sep| key.contains(sep)) {
146 let splits: Vec<&str> = FIELD_SEPARATOR.read_with(|it| key.split(it).collect());
147 self.deep_put(&splits, value)
148 } else {
149 self.data = self.data.update(key.to_string(), value);
150 Ok(())
151 }
152 }
153
154 pub fn get(&self, key: &str) -> NitriteResult<Value> {
203 match self.data.get(key) {
204 Some(value) => Ok(value.clone()),
205 None => {
206 if FIELD_SEPARATOR.read_with(|sep| key.contains(sep)) {
208 self.deep_get(key)
209 } else {
210 Ok(Value::Null)
211 }
212 }
213 }
214 }
215
216 pub fn id(&mut self) -> NitriteResult<NitriteId> {
249 if let Some(Value::NitriteId(id)) = self.data.get(DOC_ID) {
250 Ok(*id)
251 } else {
252 let nitrite_id = NitriteId::new();
255 self.data = self.data.update(
256 DOC_ID.to_string(),
257 Value::NitriteId(nitrite_id),
258 );
259 Ok(nitrite_id)
260 }
261 }
262
263 pub fn fields(&self) -> FieldVec {
308 self.get_fields_internal("")
309 }
310
311 pub fn has_id(&self) -> bool {
328 self.data.contains_key(DOC_ID)
329 }
330
331 pub fn remove(&mut self, key: &str) -> NitriteResult<()> {
374 if FIELD_SEPARATOR.read_with(|sep| key.contains(sep)) {
375 let splits: Vec<&str> = FIELD_SEPARATOR.read_with(|it| key.split(it).collect());
378 self.deep_remove(&splits)
379 } else {
380 self.data = self.data.without(key);
381 Ok(())
382 }
383 }
384
385 pub fn size(&self) -> usize {
406 self.data.len()
407 }
408
409 pub fn merge(&mut self, other: &Document) -> NitriteResult<()> {
452 for (key, value) in other.data.iter() {
453 match value {
454 Value::Document(obj) => {
455 if let Some(Value::Document(mut nested_obj)) = self.data.get(key).cloned() {
457 nested_obj.merge(obj)?;
458 self.data = self.data.update(key.clone(), Value::Document(nested_obj));
459 } else {
460 self.data = self.data.update(key.clone(), value.clone());
462 }
463 }
464 _ => {
465 self.data = self.data.update(key.clone(), value.clone());
467 }
468 }
469 }
470 Ok(())
471 }
472
473 pub fn contains_key(&self, key: &str) -> bool {
501 self.data.contains_key(key)
502 }
503
504 pub fn contains_field(&self, field: &str) -> bool {
538 if self.contains_key(field) {
539 true
540 } else {
541 self.fields().contains(&field.to_string())
542 }
543 }
544
545 pub fn revision(&self) -> NitriteResult<i32> {
567 if let Ok(Value::I32(revision)) = self.get(DOC_REVISION) {
568 Ok(revision)
569 } else {
570 Ok(0)
571 }
572 }
573
574 pub fn source(&self) -> NitriteResult<String> {
592 if let Ok(Value::String(source)) = self.get(DOC_SOURCE) {
593 Ok(source.clone())
594 } else {
595 Ok("".to_string())
596 }
597 }
598
599 pub fn last_modified_since_epoch(&self) -> NitriteResult<i64> {
620 if let Ok(Value::I64(modified)) = self.get(DOC_MODIFIED) {
621 Ok(modified)
622 } else {
623 Ok(0)
624 }
625 }
626
627 pub fn to_map(&self) -> BTreeMap<String, Value> {
645 self.data.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
646 }
647
648 pub fn iter(&self) -> DocumentIter {
678 DocumentIter {
679 keys: self.data.keys().cloned().collect(),
680 data: self.clone(),
681 index: 0,
682 }
683 }
684
685 pub(crate) fn to_pretty_json(&self, indent: usize) -> String {
686 if self.data.is_empty() {
687 return "{}".to_string();
688 }
689
690 let estimated_size = self.data.len() * 30 + indent * 2;
691 let mut json_string = String::with_capacity(estimated_size);
692
693 json_string.push_str("{\n");
694 let indent_str = " ".repeat(indent + 2);
695 for (key, value) in self.data.iter() {
696 json_string.push_str(&format!(
697 "{}\"{}\": {},\n",
698 indent_str,
699 key,
700 value.to_pretty_json(indent + 2)
701 ));
702 }
703
704 json_string.pop();
705 json_string.pop();
706 json_string.push_str(&format!("\n{}}}", " ".repeat(indent)));
707 json_string
708 }
709
710 pub(crate) fn to_debug_string(&self, indent: usize) -> String {
711 if self.data.is_empty() {
712 return "{}".to_string();
713 }
714
715 let mut debug_string = String::new();
716 debug_string.push_str("{\n");
717 let indent_str = " ".repeat(indent + 2);
718 for (key, value) in self.data.iter() {
719 debug_string.push_str(&format!(
720 "{}\"{}\": {},\n",
721 indent_str,
722 key,
723 value.to_debug_string(indent + 2)
724 ));
725 }
726
727 debug_string.pop();
728 debug_string.pop();
729 debug_string.push_str(&format!("\n{}}}", " ".repeat(indent)));
730 debug_string
731 }
732
733 fn is_embedded(&self, key: &str) -> bool {
734 FIELD_SEPARATOR.read_with(|it| key.contains(it))
735 }
736
737 fn get_fields_internal(&self, prefix: &str) -> FieldVec {
738 let mut fields = FieldVec::new();
739 let separator = FIELD_SEPARATOR.read_with(|s| s.clone());
740
741 for key in self.data.keys() {
743 if RESERVED_FIELDS.contains(&key.as_str()) {
745 continue;
746 }
747
748 if key.is_empty() {
749 continue;
750 }
751
752 let field = if prefix.is_empty() {
753 key.clone()
755 } else {
756 format!("{}{}{}", prefix, separator, key)
758 };
759
760 if let Some(Value::Document(doc)) = self.data.get(key) {
761 fields.append(&mut doc.get_fields_internal(&field));
764 } else {
765 fields.push(field);
767 }
768 }
769 fields
770 }
771
772 fn deep_get(&self, key: &str) -> NitriteResult<Value> {
773 if !self.is_embedded(key) {
774 Ok(Value::Null)
775 } else {
776 self.get_by_embedded_key(key)
777 }
778 }
779
780 fn deep_put(&mut self, splits: &[&str], value: Value) -> NitriteResult<()> {
781 if splits.is_empty() {
782 log::error!("Empty embedded key");
783 return Err(NitriteError::new(
784 "Empty embedded key",
785 ErrorKind::ValidationError,
786 ));
787 }
788
789 let key = splits[0];
790 if key.is_empty() {
791 log::error!("Document does not support empty key");
792 return Err(NitriteError::new(
793 "Document does not support empty key",
794 ErrorKind::InvalidOperation,
795 ));
796 }
797
798 if splits.len() == 1 {
799 self.put(key, value)
801 } else {
802 let remaining_splits = &splits[1..];
803 if let Some(Value::Document(mut obj)) = self.data.get(key).cloned() {
804 let result = obj.deep_put(remaining_splits, value);
806 self.data = self.data.update(key.to_string(), Value::Document(obj));
807 result
808 } else {
809 let mut nested_doc = Document::new();
811 let result = nested_doc.deep_put(remaining_splits, value);
812 self.data = self.data.update(key.to_string(), Value::Document(nested_doc));
813 result
814 }
815 }
816 }
817
818 fn deep_remove(&mut self, splits: &[&str]) -> NitriteResult<()> {
819 if splits.is_empty() {
820 log::error!("Empty embedded key");
821 return Err(NitriteError::new(
822 "Empty embedded key",
823 ErrorKind::ValidationError,
824 ));
825 }
826
827 let key = splits[0];
828 if key.is_empty() {
829 log::error!("Document does not support empty key");
830 return Err(NitriteError::new(
831 "Document does not support empty key",
832 ErrorKind::InvalidOperation,
833 ));
834 }
835
836 if splits.len() == 1 {
837 self.remove(key)
839 } else {
840 let remaining_splits = &splits[1..];
841
842 match self.data.get(key) {
843 Some(Value::Document(obj)) => {
844 let mut nested_doc = obj.clone();
846 let result = nested_doc.deep_remove(remaining_splits);
847 if nested_doc.is_empty() {
848 self.data = self.data.without(key);
851 } else {
852 self.data = self.data.update(key.to_string(), Value::Document(nested_doc));
853 }
854 result
855 }
856 Some(Value::Array(arr)) => {
857 let first = splits[1];
858 if let Ok(index) = first.parse::<isize>() {
861 if index < 0 {
862 log::error!(
863 "Invalid array index {} to access array inside a document",
864 &index
865 );
866 return Err(NitriteError::new(
867 &format!(
868 "Invalid array index {} to access array inside a document",
869 &index
870 ),
871 ErrorKind::ValidationError,
872 ));
873 }
874
875 let index = index as usize;
876 if index >= arr.len() {
877 log::error!("Array index {} out of bound", &index);
878 return Err(NitriteError::new(
879 &format!("Array index {} out of bound", &index),
880 ErrorKind::ValidationError,
881 ));
882 }
883
884 let item = &arr[index];
885 if let (Value::Document(obj), true) = (item, splits.len() > 2) {
886 let mut nested_doc = obj.clone();
888 let result = nested_doc.deep_remove(&remaining_splits[1..]);
889 if nested_doc.is_empty() {
890 let mut new_arr = arr.clone();
893 new_arr.remove(index);
894 self.data = self.data.update(key.to_string(), Value::Array(new_arr));
895 } else {
896 let mut new_arr = arr.clone();
897 new_arr[index] = Value::Document(nested_doc);
898 self.data = self.data.update(key.to_string(), Value::Array(new_arr));
899 }
900 result
901 } else {
902 let mut new_arr = arr.clone();
904 new_arr.remove(index);
905 self.data = self.data.update(key.to_string(), Value::Array(new_arr));
906 Ok(())
907 }
908 } else {
909 log::error!(
910 "Invalid array index {} to access array inside a document",
911 first
912 );
913 Err(NitriteError::new(
914 &format!(
915 "Invalid array index {} to access array inside a document",
916 first
917 ),
918 ErrorKind::ValidationError,
919 ))
920 }
921 }
922 _ => {
923 self.data = self.data.without(key);
925 Ok(())
926 }
927 }
928 }
929 }
930
931 fn get_by_embedded_key(&self, key: &str) -> NitriteResult<Value> {
932 let separator = FIELD_SEPARATOR.read_with(|s| s.clone());
933 let splits: Vec<&str> = key.split(&separator).collect();
934
935 if splits.is_empty() {
936 return Ok(Value::Null);
937 }
938
939 let first = splits[0];
940 if first.is_empty() {
941 log::error!("Document does not support empty key");
942 return Err(NitriteError::new(
943 "Document does not support empty key",
944 ErrorKind::InvalidOperation,
945 ));
946 }
947
948 self.recursive_get(self.data.get(first), &splits[1..])
950 }
951
952 fn recursive_get(&self, value: Option<&Value>, splits: &[&str]) -> NitriteResult<Value> {
953 let value = match value {
954 None => return Ok(Value::Null),
955 Some(v) => v,
956 };
957
958 if splits.is_empty() {
959 return Ok(value.clone());
960 }
961
962 let key = splits[0];
963 if key.is_empty() {
964 log::error!("Document does not support empty key");
965 return Err(NitriteError::new(
966 "Document does not support empty key",
967 ErrorKind::InvalidOperation,
968 ));
969 }
970
971 match value {
972 Value::Document(obj) => {
973 self.recursive_get(obj.data.get(key), &splits[1..])
975 }
976 Value::Array(arr) => {
977 let first = key;
979 if let Ok(index) = first.parse::<isize>() {
980 if index < 0 {
982 log::error!(
983 "Invalid array index {} to access array inside a document",
984 &index
985 );
986 return Err(NitriteError::new(
987 &format!(
988 "Invalid array index {} to access array inside a document",
989 &index
990 ),
991 ErrorKind::ValidationError,
992 ));
993 }
994
995 let index = index as usize;
997 if index >= arr.len() {
998 log::error!("Array index {} out of bound", &index);
999 return Err(NitriteError::new(
1000 &format!("Array index {} out of bound", &index),
1001 ErrorKind::ValidationError,
1002 ));
1003 }
1004
1005 let item = &arr[index];
1007 self.recursive_get(Some(item), &splits[1..])
1008 } else {
1009 self.decompose(arr, splits)
1011 }
1012 }
1013 _ => Ok(Value::Null), }
1015 }
1016
1017 fn decompose(&self, arr: &[Value], splits: &[&str]) -> NitriteResult<Value> {
1018 let mut items: Vec<Value> = Vec::with_capacity(arr.len());
1019
1020 for item in arr {
1021 let result = self.recursive_get(Some(item), splits)?;
1023
1024 match result {
1025 Value::Array(arr) => {
1026 for v in arr {
1028 items.push(v);
1029 }
1030 }
1031 value => {
1032 items.push(value);
1034 }
1035 }
1036 }
1037 Ok(Value::Array(items.iter().unique().cloned().collect::<Vec<_>>()))
1039 }
1040}
1041
1042impl Debug for Document {
1043 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1044 write!(f, "{}", self.to_debug_string(0))
1045 }
1046}
1047
1048impl Display for Document {
1049 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1050 write!(f, "{}", self.to_pretty_json(0))
1051 }
1052}
1053
1054pub struct DocumentIter {
1055 keys: Vec<String>,
1056 data: Document,
1057 index: usize,
1058}
1059
1060impl Iterator for DocumentIter {
1061 type Item = (String, Value);
1062
1063 fn next(&mut self) -> Option<Self::Item> {
1064 if self.index < self.keys.len() {
1065 let key = &self.keys[self.index];
1066 if let Some(value) = self.data.data.get(key) {
1067 let result = (key.clone(), value.clone());
1068 self.index += 1;
1069 return Some(result);
1070 }
1071 self.index += 1;
1072 self.next()
1073 } else {
1074 None
1075 }
1076 }
1077
1078 fn size_hint(&self) -> (usize, Option<usize>) {
1079 let remaining = self.keys.len().saturating_sub(self.index);
1080 (remaining, Some(remaining))
1081 }
1082}
1083
1084pub fn normalize(value: &str) -> String {
1085 value.trim_matches('"').to_string()
1086}
1087
1088#[macro_export]
1122macro_rules! doc {
1123 ({}) => {
1125 $crate::collection::Document::new()
1126 };
1127
1128 () => {
1130 $crate::collection::Document::new()
1131 };
1132
1133 ({ $($key:tt : $value:tt),* $(,)? }) => {
1135 $crate::doc!($($key : $value),*)
1136 };
1137
1138 ($($key:tt : $value:tt),* $(,)?) => {
1140 {
1141 #[allow(unused_imports)]
1142 use $crate::doc_value;
1143
1144 let mut doc = $crate::collection::Document::new();
1145 $(
1146 doc.put(&$crate::collection::normalize(stringify!($key)), $crate::doc_value!($value))
1147 .expect(&format!("Failed to put value {} in document", stringify!($value)));
1148 )*
1149 doc
1150 }
1151 };
1152}
1153
1154#[macro_export]
1157macro_rules! doc_value {
1158 ({ $($key:tt : $value:tt),* $(,)? }) => {
1160 {
1161 $crate::common::Value::Document($crate::doc!{ $($key : $value),* })
1162 }
1163 };
1164
1165 ([ $($value:tt),* $(,)? ]) => {
1167 $crate::common::Value::Array(vec![$($crate::doc_value!($value)),*])
1168 };
1169
1170 ($value:expr) => {
1172 $crate::common::Value::from($value)
1173 };
1174}
1175
1176#[cfg(test)]
1177mod tests {
1178 use std::string;
1179
1180 use super::*;
1181 use crate::collection::Document;
1182 use crate::common::Value::Null;
1183 use crate::{create_document, document_from_map, empty_document};
1184
1185 fn set_up() -> Document {
1186 doc!{
1187 score: 1034,
1188 location: {
1189 state: "NY",
1190 city: "New York",
1191 address: {
1192 line1: "40",
1193 line2: "ABC Street",
1194 house: ["1", "2", "3"],
1195 zip: 10001,
1196 },
1197 },
1198 category: ["food", "produce", "grocery"],
1199 obj_array: [
1200 {
1201 value: 1,
1202 },
1203 {
1204 value: 2,
1205 },
1206 ]
1207 }
1208 }
1209
1210 #[test]
1211 fn test_normalize() {
1212 let value = "\"ABC\"".to_string();
1213 let result = normalize(&value);
1214 assert_eq!(result, "ABC");
1215
1216 let value = "ABC".to_string();
1217 let result = normalize(&value);
1218 assert_eq!(result, "ABC");
1219 }
1220
1221 #[test]
1222 fn test_empty_document() {
1223 let doc = empty_document();
1224 assert!(doc.is_empty());
1225 }
1226
1227 #[test]
1228 fn test_new() {
1229 let doc = Document::new();
1230 assert!(doc.is_empty());
1231 }
1232
1233 #[test]
1234 fn test_document_from_map() {
1235 let mut map = BTreeMap::new();
1236 map.insert("key1".to_string(), Value::I32(1));
1237 map.insert("key2".to_string(), Value::String("value".to_string()));
1238 map.insert(
1239 "key3".to_string(),
1240 Value::Array(vec![Value::I32(1), Value::I32(2)]),
1241 );
1242 map.insert("key4".to_string(), Value::Document(Document::new()));
1243
1244 let doc = document_from_map(&map).unwrap();
1245 assert_eq!(doc.size(), 4);
1246 }
1247
1248 #[test]
1249 fn test_create_document() {
1250 let doc = create_document("key", Value::I32(1)).unwrap();
1251 assert_eq!(doc.size(), 1);
1252 }
1253
1254 #[test]
1255 fn test_is_empty() {
1256 let doc = empty_document();
1257 assert!(doc.is_empty());
1258
1259 let doc = set_up();
1260 assert!(!doc.is_empty());
1261 }
1262
1263 #[test]
1264 fn test_get() {
1265 let doc = set_up();
1266 let mut value = doc.get("").unwrap();
1267 assert_eq!(value, Null);
1268 value = doc.get("score").unwrap();
1269 assert_eq!(value, Value::I32(1034));
1270 value = doc.get("location.state").unwrap();
1271 assert_eq!(value, Value::String("NY".to_string()));
1272 value = doc.get("location.address").unwrap();
1273 assert_eq!(
1274 value,
1275 Value::Document(doc!{
1276 line1: "40",
1277 line2: "ABC Street",
1278 house: ["1", "2", "3"],
1279 zip: 10001,
1280 })
1281 );
1282 value = doc.get("location.address.line1").unwrap();
1283 assert_eq!(value, Value::String("40".to_string()));
1284 value = doc.get("location.address.line2").unwrap();
1285 assert_eq!(value, Value::String("ABC Street".to_string()));
1286 value = doc.get("location.address.house").unwrap();
1287 assert_eq!(
1288 value,
1289 Value::Array(vec![
1290 Value::String("1".to_string()),
1291 Value::String("2".to_string()),
1292 Value::String("3".to_string())
1293 ])
1294 );
1295 value = doc.get("location.address.house.0").unwrap();
1296 assert_eq!(value, Value::String("1".to_string()));
1297 value = doc.get("location.address.house.1").unwrap();
1298 assert_eq!(value, Value::String("2".to_string()));
1299 value = doc.get("location.address.house.2").unwrap();
1300 assert_eq!(value, Value::String("3".to_string()));
1301 value = doc.get("location.address.zip").unwrap();
1302 assert_eq!(value, Value::I32(10001));
1303
1304 value = doc.get("category").unwrap();
1305 assert_eq!(
1306 value,
1307 Value::Array(vec![
1308 Value::String("food".to_string()),
1309 Value::String("produce".to_string()),
1310 Value::String("grocery".to_string())
1311 ])
1312 );
1313 value = doc.get("category.0").unwrap();
1314 assert_eq!(value, Value::String("food".to_string()));
1315 value = doc.get("category.1").unwrap();
1316 assert_eq!(value, Value::String("produce".to_string()));
1317 value = doc.get("category.2").unwrap();
1318 assert_eq!(value, Value::String("grocery".to_string()));
1319
1320 value = doc.get("obj_array").unwrap();
1321 assert_eq!(
1322 value,
1323 Value::Array(vec![
1324 Value::Document(doc!{ value: 1 }),
1325 Value::Document(doc!{ value: 2 }),
1326 ])
1327 );
1328 value = doc.get("obj_array.0").unwrap();
1329 assert_eq!(value, Value::Document(doc!{ value: 1 }));
1330 value = doc.get("obj_array.1").unwrap();
1331 assert_eq!(value, Value::Document(doc!{ value: 2 }));
1332 value = doc.get("obj_array.0.value").unwrap();
1333 assert_eq!(value, Value::I32(1));
1334 value = doc.get("obj_array.1.value").unwrap();
1335 assert_eq!(value, Value::I32(2));
1336
1337 value = doc.get("location.address.test").unwrap();
1338 assert_eq!(value, Null);
1339 assert!(doc.get("location.address.house.3").is_err());
1340 assert!(doc.get("location.address.house.-1").is_err());
1341 assert!(doc.get(".").is_err());
1342 assert!(doc.get("..").is_err());
1343 assert_eq!(doc.get("score.test").unwrap(), Null);
1344 }
1345
1346 #[test]
1347 fn test_put_null() {
1348 let mut doc = empty_document();
1349 doc.put("key", Null).unwrap();
1350 assert_eq!(doc.size(), 1);
1351 assert_eq!(doc.get("key").unwrap(), Null);
1352 }
1353
1354 #[test]
1355 fn test_put_and_get() {
1356 let mut doc = Document::new();
1357 doc.put("key", Value::I32(1)).unwrap();
1358 assert_eq!(doc.get("key").unwrap(), Value::I32(1));
1359 }
1360
1361 #[test]
1362 fn test_put_empty_key() {
1363 let mut doc = Document::new();
1364 let result = doc.put("", Value::I32(1));
1365 assert!(result.is_err());
1366 }
1367
1368 #[test]
1369 fn test_put_reserved_id() {
1370 let mut doc = Document::new();
1371 let result = doc.put(DOC_ID, Value::String("id".to_string()));
1372 assert!(result.is_err());
1373 }
1374
1375 #[test]
1376 fn test_put_id() {
1377 let mut doc = empty_document();
1378 let result = doc.put(DOC_ID, Value::String("id".to_string()));
1379 assert!(result.is_err());
1380 }
1381
1382 #[test]
1383 fn test_put_valid_nitrite_id() {
1384 let mut doc = empty_document();
1385 let result = doc.put(DOC_ID, Value::NitriteId(NitriteId::new()));
1386 assert!(result.is_ok());
1387 }
1388
1389 #[test]
1390 fn test_get_invalid_id() {
1391 let mut map = BTreeMap::new();
1393 map.insert(DOC_ID.to_string(), Value::String("invalid_id".to_string()));
1394
1395 let err = document_from_map(&map).is_err();
1396 assert!(err);
1397 }
1398
1399 #[test]
1400 fn test_get_non_existent_key() {
1401 let doc = Document::new();
1402 assert_eq!(doc.get("non_existent").unwrap(), Null);
1403 }
1404
1405 #[test]
1406 fn test_invalid_get() {
1407 let key = "first.array.-1";
1408 let doc = doc!{
1409 first: {
1410 array: [1, 2, 3],
1411 },
1412 };
1413 let err = doc.get(key).is_err();
1414 assert!(err);
1415 }
1416
1417 #[test]
1418 fn test_id() {
1419 let mut doc = empty_document();
1420 let id = doc.id().unwrap();
1421 assert!(NitriteId::valid_id(id.id_value()).unwrap());
1422 assert!(doc.has_id());
1423 }
1424
1425 #[test]
1426 fn test_fields() {
1427 let doc = doc!{
1428 key1: 1,
1429 key2: "value",
1430 key3: [1, 2, 3],
1431 key4: {
1432 key5: 5,
1433 key6: "value",
1434 },
1435 };
1436 let fields = doc.fields();
1437 assert_eq!(fields.len(), 5);
1438 }
1439
1440 #[test]
1441 fn test_has_id() {
1442 let mut doc = empty_document();
1443 assert!(!doc.has_id());
1444 doc.put(DOC_ID, Value::NitriteId(NitriteId::new())).unwrap();
1445 assert!(doc.has_id());
1446 }
1447
1448 #[test]
1449 fn test_contains_key() {
1450 let doc = set_up();
1451 assert!(doc.contains_key("score"));
1452 assert!(!doc.contains_key("non_existent"));
1453 }
1454
1455 #[test]
1456 fn test_contains_field() {
1457 let doc = set_up();
1458 assert!(doc.contains_field("location.state"));
1459 assert!(!doc.contains_field("location.country"));
1460 }
1461
1462 #[test]
1463 fn test_remove() {
1464 let mut doc = empty_document();
1465 doc.put("key", Value::I32(1)).unwrap();
1466 assert_eq!(doc.size(), 1);
1467 doc.remove("key").unwrap();
1468 assert_eq!(doc.size(), 0);
1469 }
1470
1471 #[test]
1472 fn test_size() {
1473 let doc = set_up();
1474 assert_eq!(doc.size(), 4);
1475 }
1476
1477 #[test]
1478 fn test_revision() {
1479 let mut doc = Document::new();
1480 doc.put(DOC_REVISION, Value::I32(1)).unwrap();
1481 assert_eq!(doc.revision().unwrap(), 1);
1482 }
1483
1484 #[test]
1485 fn test_source() {
1486 let mut doc = Document::new();
1487 doc.put(DOC_SOURCE, Value::String("source".to_string())).unwrap();
1488 assert_eq!(doc.source().unwrap(), "source");
1489 }
1490
1491 #[test]
1492 fn test_last_modified_since_epoch() {
1493 let mut doc = Document::new();
1494 doc.put(DOC_MODIFIED, Value::I64(123456789)).unwrap();
1495 assert_eq!(doc.last_modified_since_epoch().unwrap(), 123456789);
1496 }
1497
1498 #[test]
1499 fn test_to_map() {
1500 let doc = set_up();
1501 let map = doc.to_map();
1502 assert_eq!(map.len(), 4);
1503 }
1504
1505 #[test]
1506 fn test_iter() {
1507 let doc = doc!{
1508 key1: "value1",
1509 key2: 2,
1510 };
1511
1512 let mut iter = doc.iter();
1513 let (key, value) = iter.next().unwrap();
1514 assert_eq!(key, "key1");
1515 assert_eq!(value, Value::String("value1".to_string()));
1516
1517 let (key, value) = iter.next().unwrap();
1518 assert_eq!(key, "key2");
1519 assert_eq!(value, Value::I32(2));
1520 }
1521
1522 #[test]
1523 fn test_get_fields() {
1524 let doc = set_up();
1525 let fields = doc.fields();
1526 assert_eq!(fields.len(), 9);
1527
1528 assert!(fields.contains(&"score".to_string()));
1529 assert!(fields.contains(&"location.state".to_string()));
1530 assert!(fields.contains(&"location.city".to_string()));
1531 assert!(fields.contains(&"location.address.line1".to_string()));
1532 assert!(fields.contains(&"location.address.line2".to_string()));
1533 assert!(fields.contains(&"location.address.house".to_string()));
1534 assert!(fields.contains(&"location.address.zip".to_string()));
1535 assert!(fields.contains(&"category".to_string()));
1536 assert!(fields.contains(&"obj_array".to_string()));
1537 }
1538
1539 #[test]
1540 fn test_get_embedded_array_fields() {
1541 let doc = doc!{
1542 first: "value",
1543 second: ["1", "2"],
1544 third: Null,
1545 fourth: {
1546 first: "value",
1547 second: ["1", "2"],
1548 third: {
1549 first: [1, 2],
1550 second: "other",
1551 },
1552 },
1553 fifth: [
1554 {
1555 first: "value",
1556 second: [1, 2, 3],
1557 third: {
1558 first: "value",
1559 second: [1, 2],
1560 },
1561 fourth: [
1562 {
1563 first: "value",
1564 second: [1, 2],
1565 },
1566 {
1567 first: "value",
1568 second: [1, 2],
1569 },
1570 ],
1571 },
1572 {
1573 first: "value",
1574 second: [3, 4, 5],
1575 third: {
1576 first: "value",
1577 second: [1, 2],
1578 },
1579 fourth: [
1580 {
1581 first: "value",
1582 second: [1, 2],
1583 },
1584 {
1585 first: "value",
1586 second: [1, 2],
1587 },
1588 ],
1589 },
1590 {
1591 first: "value",
1592 second: [5, 6, 7],
1593 third: {
1594 first: "value",
1595 second: [1, 2],
1596 },
1597 fourth: [
1598 {
1599 first: "value",
1600 second: [1, 2],
1601 },
1602 {
1603 first: "value",
1604 second: [3, 4],
1605 },
1606 ],
1607 },
1608 ]
1609 };
1610
1611 let val = doc.get("fifth.second").unwrap();
1612 let list = val.as_array().unwrap();
1613 assert_eq!(list.len(), 7);
1614
1615 let val = doc.get("fifth.fourth.second").unwrap();
1616 let list = val.as_array().unwrap();
1617 assert_eq!(list.len(), 4);
1618
1619 let val = doc.get("fourth.third.second").unwrap();
1620 assert_eq!(val, Value::String("other".to_string()));
1621
1622 let val = doc.get("fifth.0.second.0").unwrap();
1623 assert_eq!(val, Value::I32(1));
1624
1625 let val = doc.get("fifth.1.fourth.0.second.1").unwrap();
1626 assert_eq!(val, Value::I32(2));
1627 }
1628
1629 #[test]
1630 fn test_deep_put() {
1631 let mut doc = set_up();
1632 doc.put("location.address.pin", Value::I32(700037)).unwrap();
1633 assert_eq!(doc.get("location.address.pin").unwrap(), Value::I32(700037));
1634
1635 doc.put("location.address.business.pin", Value::I32(700037))
1636 .unwrap();
1637 assert_eq!(
1638 doc.get("location.address.business.pin").unwrap(),
1639 Value::I32(700037)
1640 );
1641 }
1642
1643 #[test]
1644 fn test_deep_remove() {
1645 let mut doc = set_up();
1646 doc.remove("location.address.zip").unwrap();
1647 assert_eq!(doc.get("location.address.zip").unwrap(), Null);
1648
1649 doc.remove("location.address.line1").unwrap();
1650 assert_eq!(doc.get("location.address.line1").unwrap(), Null);
1651
1652 doc.remove("location.address.line2").unwrap();
1653 assert_eq!(doc.get("location.address.line2").unwrap(), Null);
1654
1655 doc.remove("location.address.house").unwrap();
1656 assert_eq!(doc.get("location.address.house").unwrap(), Null);
1657
1658 doc.remove("location.address").unwrap();
1659 assert_eq!(doc.get("location.address").unwrap(), Null);
1660 }
1661
1662 #[test]
1663 fn test_deep_get() {
1664 let doc = set_up();
1665 let value = doc.get("location.address.line1").unwrap();
1666 assert_eq!(value, Value::String("40".to_string()));
1667 }
1668
1669 #[test]
1670 fn test_recursive_get() {
1671 let doc = set_up();
1672 let value = doc.get("location.address.house.0").unwrap();
1673 assert_eq!(value, Value::String("1".to_string()));
1674 }
1675
1676 #[test]
1677 fn test_decompose() {
1678 let doc = doc!{
1679 some_key: [{key: 1}, {key: 2}, {key: 3}],
1680 };
1681
1682 let value = doc.get("some_key").unwrap();
1683 let array = value.as_array().unwrap();
1684 let decomposed = doc.decompose(array, &["key"]).unwrap();
1685 assert_eq!(decomposed, Value::Array(vec![Value::I32(1), Value::I32(2), Value::I32(3)]));
1686 }
1687
1688 #[test]
1689 fn test_deep_put_invalid_field() {
1690 let mut doc = empty_document();
1691 let result = doc.put("..invalid..field", Value::I32(1));
1692 assert!(result.is_err());
1693 }
1694
1695 #[test]
1696 fn test_deep_remove_invalid_field() {
1697 let mut doc = empty_document();
1698 let result = doc.remove("..invalid..field");
1699 assert!(result.is_err());
1700 }
1701
1702 #[test]
1703 fn test_merge_documents() {
1704 let mut doc1 = doc!{
1705 "key1": "value1",
1706 "nested": {
1707 "key2": "value2",
1708 },
1709 };
1710
1711 let doc2 = doc!{
1712 "key3": "value3",
1713 "nested": {
1714 "key4": "value4",
1715 },
1716 };
1717
1718 doc1.merge(&doc2).unwrap();
1719 assert_eq!(doc1.size(), 3);
1720 assert_eq!(
1721 doc1.get("key1").unwrap(),
1722 Value::String("value1".to_string())
1723 );
1724 assert_eq!(
1725 doc1.get("key3").unwrap(),
1726 Value::String("value3".to_string())
1727 );
1728 assert_eq!(
1729 doc1.get("nested.key2").unwrap(),
1730 Value::String("value2".to_string())
1731 );
1732 assert_eq!(
1733 doc1.get("nested.key4").unwrap(),
1734 Value::String("value4".to_string())
1735 );
1736 }
1737
1738 #[test]
1739 fn test_display() {
1740 let doc = doc!{
1741 key1: "value1",
1742 key2: 2,
1743 };
1744
1745 let display = format!("{}", doc);
1746 assert!(display.contains("\"key1\": \"value1\""));
1747 assert!(display.contains("\"key2\": 2"));
1748 }
1749
1750 #[test]
1751 fn test_debug() {
1752 let doc = doc!{
1753 key1: "value1",
1754 key2: 2,
1755 };
1756
1757 let debug = format!("{:?}", doc);
1758 assert!(debug.contains("\"key1\": string(\"value1\")"));
1759 assert!(debug.contains("\"key2\": i32(2)"));
1760 }
1761
1762 #[test]
1763 fn test_put_invalid_id() {
1764 let mut doc = empty_document();
1765 let result = doc.put(DOC_ID, Value::String("invalid_id".to_string()));
1766 assert!(result.is_err());
1767 }
1768
1769 #[test]
1770 fn test_get_invalid_key() {
1771 let doc = empty_document();
1772 let result = doc.get("invalid.key");
1773 assert!(result.is_ok());
1774 assert_eq!(result.unwrap(), Null);
1775 }
1776
1777 #[test]
1778 fn test_remove_invalid_key() {
1779 let mut doc = empty_document();
1780 let result = doc.remove("invalid.key");
1781 assert!(result.is_ok());
1782 }
1783
1784 #[test]
1785 fn test_merge_empty_document() {
1786 let mut doc1 = empty_document();
1787 let doc2 = empty_document();
1788 doc1.merge(&doc2).unwrap();
1789 assert_eq!(doc1.size(), 0);
1790 }
1791
1792 #[test]
1793 fn test_get_invalid_array_index() {
1794 let doc = doc!{
1795 key: [1, 2, 3],
1796 };
1797
1798 let result = doc.get("key.-1");
1799 assert!(result.is_err());
1800 }
1801
1802 #[test]
1803 fn test_remove_invalid_array_index() {
1804 let mut doc = doc!{
1805 key: [1, 2, 3],
1806 };
1807
1808 let result = doc.remove("key.-1");
1809 assert!(result.is_err());
1810 }
1811
1812 #[test]
1813 fn test_merge_conflicting_keys() {
1814 let mut doc1 = doc!{
1815 key1: "value1",
1816 key2: "value2",
1817 };
1818
1819 let doc2 = doc!{
1820 key2: "value3",
1821 key3: "value4",
1822 };
1823
1824 doc1.merge(&doc2).unwrap();
1825 assert_eq!(doc1.size(), 3);
1826 assert_eq!(
1827 doc1.get("key1").unwrap(),
1828 Value::String("value1".to_string())
1829 );
1830 assert_eq!(
1831 doc1.get("key2").unwrap(),
1832 Value::String("value3".to_string())
1833 );
1834 assert_eq!(
1835 doc1.get("key3").unwrap(),
1836 Value::String("value4".to_string())
1837 );
1838 }
1839
1840 #[test]
1841 fn test_deep_put_invalid_path() {
1842 let mut doc = empty_document();
1843 let result = doc.put("key..key", Value::I32(1));
1844 assert!(result.is_err());
1845 }
1846
1847 #[test]
1848 fn test_deep_get_invalid_path() {
1849 let doc = set_up();
1850 let result = doc.get("location..key");
1851 assert!(result.is_err());
1852 }
1853
1854 #[test]
1855 fn contains_field_with_existing_field() {
1856 let doc = set_up();
1857 assert!(doc.contains_field("location.state"));
1858 }
1859
1860 #[test]
1861 fn contains_field_with_non_existing_field() {
1862 let doc = set_up();
1863 assert!(!doc.contains_field("location.country"));
1864 }
1865
1866 #[test]
1867 fn revision_with_existing_revision() {
1868 let mut doc = empty_document();
1869 doc.put(DOC_REVISION, Value::I32(1)).unwrap();
1870 assert_eq!(doc.revision().unwrap(), 1);
1871 }
1872
1873 #[test]
1874 fn revision_with_non_existing_revision() {
1875 let doc = empty_document();
1876 assert_eq!(doc.revision().unwrap(), 0);
1877 }
1878
1879 #[test]
1880 fn source_with_existing_source() {
1881 let mut doc = empty_document();
1882 doc.put(DOC_SOURCE, Value::String("source".to_string()))
1883 .unwrap();
1884 assert_eq!(doc.source().unwrap(), "source");
1885 }
1886
1887 #[test]
1888 fn source_with_non_existing_source() {
1889 let doc = empty_document();
1890 assert_eq!(doc.source().unwrap(), "");
1891 }
1892
1893 #[test]
1894 fn last_modified_since_epoch_with_existing_modified() {
1895 let mut doc = empty_document();
1896 doc.put(DOC_MODIFIED, Value::I64(123456789)).unwrap();
1897 assert_eq!(doc.last_modified_since_epoch().unwrap(), 123456789);
1898 }
1899
1900 #[test]
1901 fn last_modified_since_epoch_with_non_existing_modified() {
1902 let doc = empty_document();
1903 assert_eq!(doc.last_modified_since_epoch().unwrap(), 0);
1904 }
1905
1906 #[test]
1907 fn test_macro() {
1908 let string_key = "c".to_string();
1909 let document = doc!{
1910 s: string_key,
1911 a: 12,
1912 b: "c",
1913 "d": [1, 2, 3],
1914 e: ["f", "g"],
1915 h: {
1916 i: 10,
1917 j: [1, 2, 3],
1918 },
1919 k: [
1920 {
1921 l: 15,
1922 m: [10, 15],
1923 "n": {
1924 o: 1.25,
1925 },
1926 },
1927 {
1928 p: 15,
1929 q: [
1930 {
1931 r: "45",
1932 s: 1569,
1933 },
1934 {
1935 t: 20,
1936 u: 1.25,
1937 },
1938 ],
1939 }
1940 ],
1941 u: [
1942 ["v", "w"],
1943 ["x", "y", "z"],
1944 ],
1945 v: {
1946 w: {
1947 x: {
1948 y: {
1949 z: true,
1950 }
1951 }
1952 }
1953 }
1954 };
1955
1956 let mut doc2 = empty_document();
1957 doc2.put("s", Value::String("c".to_string())).unwrap();
1958 doc2.put("a", Value::I32(12)).unwrap();
1959 doc2.put("b", Value::String("c".to_string())).unwrap();
1960 doc2.put(
1961 "d",
1962 Value::Array(vec![Value::I32(1), Value::I32(2), Value::I32(3)]),
1963 )
1964 .unwrap();
1965 doc2.put(
1966 "e",
1967 Value::Array(vec![
1968 Value::String("f".to_string()),
1969 Value::String("g".to_string()),
1970 ]),
1971 )
1972 .unwrap();
1973 doc2.put("h", Value::Document(doc!{ i: 10, j: [1, 2, 3] }))
1974 .unwrap();
1975 doc2.put(
1976 "k",
1977 Value::Array(vec![
1978 Value::Document(doc!{ l: 15, m: [10, 15], "n": { o: 1.25 } }),
1979 Value::Document(doc!{ p: 15, q: [
1980 { r: "45", s: 1569 },
1981 { t: 20, u: 1.25 },
1982 ] }),
1983 ]),
1984 )
1985 .unwrap();
1986
1987 doc2.put(
1988 "u",
1989 Value::Array(vec![
1990 Value::Array(vec![
1991 Value::String("v".to_string()),
1992 Value::String("w".to_string()),
1993 ]),
1994 Value::Array(vec![
1995 Value::String("x".to_string()),
1996 Value::String("y".to_string()),
1997 Value::String("z".to_string()),
1998 ]),
1999 ]),
2000 )
2001 .unwrap();
2002
2003 doc2.put("v", Value::Document(doc!{ w: { x: { y: { z: true } } } }))
2004 .unwrap();
2005
2006 assert_eq!(document, doc2);
2007 }
2008
2009 #[test]
2010 fn test_empty_document_macro() {
2011 let doc = doc!{};
2012 assert!(doc.is_empty());
2013 }
2014
2015 #[test]
2016 fn test_document_with_key_value_string() {
2017 let doc = doc!{
2018 key: "value",
2019 };
2020 assert_eq!(doc.size(), 1);
2021 assert_eq!(doc.get("key").unwrap(), Value::String("value".to_string()));
2022 }
2023
2024 #[test]
2025 fn test_nested_document_macro() {
2026 let doc = doc!{
2027 key1: "value1",
2028 key2: {
2029 key3: "value3",
2030 },
2031 };
2032 assert_eq!(doc.size(), 2);
2033 assert_eq!(
2034 doc.get("key1").unwrap(),
2035 Value::String("value1".to_string())
2036 );
2037 assert_eq!(
2038 doc.get("key2.key3").unwrap(),
2039 Value::String("value3".to_string())
2040 );
2041 }
2042
2043 #[test]
2044 fn test_array_in_document_macro() {
2045 let doc = doc!{
2046 key1: "value1",
2047 key2: [1, 2, 3],
2048 };
2049 assert_eq!(doc.size(), 2);
2050 assert_eq!(
2051 doc.get("key1").unwrap(),
2052 Value::String("value1".to_string())
2053 );
2054 assert_eq!(
2055 doc.get("key2").unwrap(),
2056 Value::Array(vec![Value::I32(1), Value::I32(2), Value::I32(3)])
2057 );
2058 }
2059
2060 #[test]
2061 fn test_complex_document_macro() {
2062 let document = doc!{
2063 key1: "value1",
2064 key2: {
2065 nested_key1: "nested_value",
2066 nested_key2: [10, 20, 30]
2067 },
2068 key3: [true, false, {
2069 "deep_nested_key": "deep_value"
2070 }]
2071 };
2072
2073 assert_eq!(document.size(), 3);
2074 assert_eq!(
2075 document.get("key1").unwrap(),
2076 Value::String("value1".to_string())
2077 );
2078
2079 let binding = document.get("key2").unwrap();
2080 let nested_doc = binding.as_document().unwrap();
2081 assert_eq!(nested_doc.size(), 2);
2082 assert_eq!(
2083 nested_doc.get("nested_key1").unwrap(),
2084 Value::String("nested_value".to_string())
2085 );
2086
2087 let nested_array = nested_doc.get("nested_key2").unwrap();
2088 let array = nested_array.as_array().unwrap();
2089 assert_eq!(array.len(), 3);
2090 assert_eq!(array[0], Value::I32(10));
2091 assert_eq!(array[1], Value::I32(20));
2092 assert_eq!(array[2], Value::I32(30));
2093
2094 let binding = document.get("key3").unwrap();
2095 let array = binding.as_array().unwrap();
2096 assert_eq!(array.len(), 3);
2097 assert_eq!(array[0], Value::Bool(true));
2098 assert_eq!(array[1], Value::Bool(false));
2099
2100 let binding = &array[2];
2101 let nested_doc = binding.as_document().unwrap();
2102 assert_eq!(nested_doc.size(), 1);
2103 assert_eq!(
2104 nested_doc.get("deep_nested_key").unwrap(),
2105 Value::String("deep_value".to_string())
2106 );
2107 }
2108
2109 #[test]
2111 fn test_recursive_get_null_value() {
2112 let doc = Document::new();
2113 let result = doc.recursive_get(None, &[]);
2114 assert_eq!(result.unwrap(), Null);
2115 }
2116
2117 #[test]
2118 fn test_recursive_get_simple_value() {
2119 let doc = doc!{
2120 "name": "Alice",
2121 "age": 25
2122 };
2123
2124 let value = doc.get("name").unwrap();
2125 assert_eq!(value, Value::String("Alice".to_string()));
2126
2127 let value = doc.get("age").unwrap();
2128 assert_eq!(value, Value::I32(25));
2129 }
2130
2131 #[test]
2132 fn test_recursive_get_nested_document() {
2133 let doc = doc!{
2134 "user": {
2135 "profile": {
2136 "name": "Bob",
2137 "age": 30
2138 }
2139 }
2140 };
2141
2142 let value = doc.get("user").unwrap();
2143 assert!(matches!(value, Value::Document(_)));
2144
2145 let value = doc.get("user.profile").unwrap();
2146 assert!(matches!(value, Value::Document(_)));
2147
2148 let value = doc.get("user.profile.name").unwrap();
2149 assert_eq!(value, Value::String("Bob".to_string()));
2150 }
2151
2152 #[test]
2153 fn test_recursive_get_array_index() {
2154 let doc = doc!{
2155 "items": [
2156 {"name": "Item 1"},
2157 {"name": "Item 2"},
2158 {"name": "Item 3"}
2159 ]
2160 };
2161
2162 let value = doc.get("items.0").unwrap();
2163 assert!(matches!(value, Value::Document(_)));
2164
2165 let value = doc.get("items.0.name").unwrap();
2166 assert_eq!(value, Value::String("Item 1".to_string()));
2167
2168 let value = doc.get("items.2.name").unwrap();
2169 assert_eq!(value, Value::String("Item 3".to_string()));
2170 }
2171
2172 #[test]
2173 fn test_recursive_get_nonexistent_path() {
2174 let doc = doc!{
2175 "name": "Charlie",
2176 "age": 35
2177 };
2178
2179 let value = doc.get("nonexistent").unwrap();
2180 assert_eq!(value, Null);
2181
2182 let value = doc.get("name.nested").unwrap();
2183 assert_eq!(value, Null);
2184 }
2185
2186 #[test]
2187 fn test_recursive_get_deep_nesting() {
2188 let doc = doc!{
2189 "level1": {
2190 "level2": {
2191 "level3": {
2192 "level4": {
2193 "value": "deep"
2194 }
2195 }
2196 }
2197 }
2198 };
2199
2200 let value = doc.get("level1.level2.level3.level4.value").unwrap();
2201 assert_eq!(value, Value::String("deep".to_string()));
2202 }
2203
2204 #[test]
2205 fn test_recursive_get_mixed_types() {
2206 let doc = doc!{
2207 "name": "David",
2208 "age": 28,
2209 "tags": ["tag1", "tag2"],
2210 "meta": {
2211 "created": "2025-01-01"
2212 }
2213 };
2214
2215 assert_eq!(doc.get("name").unwrap(), Value::String("David".to_string()));
2216 assert_eq!(doc.get("age").unwrap(), Value::I32(28));
2217 assert!(matches!(doc.get("tags").unwrap(), Value::Array(_)));
2218 assert!(matches!(doc.get("meta").unwrap(), Value::Document(_)));
2219 }
2220
2221 #[test]
2222 fn bench_get_top_level_key() {
2223 let doc = doc!{
2224 key1: "value1",
2225 key2: "value2",
2226 key3: "value3",
2227 key4: "value4",
2228 key5: "value5",
2229 };
2230
2231 let start = std::time::Instant::now();
2232 for _ in 0..10000 {
2233 let _ = doc.get("key1");
2234 }
2235 let elapsed = start.elapsed();
2236 println!("10000 top-level get calls: {:?}", elapsed);
2237 assert!(elapsed.as_millis() < 500);
2238 }
2239
2240 #[test]
2241 fn bench_get_embedded_key() {
2242 let doc = doc!{
2243 level1: {
2244 level2: {
2245 level3: "value"
2246 }
2247 }
2248 };
2249
2250 let start = std::time::Instant::now();
2251 for _ in 0..1000 {
2252 let _ = doc.get("level1.level2.level3");
2253 }
2254 let elapsed = start.elapsed();
2255 println!("1000 embedded get calls: {:?}", elapsed);
2256 assert!(elapsed.as_millis() < 200);
2257 }
2258
2259 #[test]
2260 fn bench_put_operations() {
2261 let start = std::time::Instant::now();
2262 for i in 0..1000 {
2263 let mut doc = Document::new();
2264 doc.put(format!("key{}", i), Value::I32(i)).ok();
2265 }
2266 let elapsed = start.elapsed();
2267 println!("1000 put operations: {:?}", elapsed);
2268 assert!(elapsed.as_millis() < 300);
2269 }
2270
2271 #[test]
2272 fn bench_merge_documents() {
2273 let start = std::time::Instant::now();
2274 for _ in 0..100 {
2275 let mut doc1 = doc!{
2276 key1: "value1",
2277 nested: {
2278 key2: "value2",
2279 }
2280 };
2281 let doc2 = doc!{
2282 key3: "value3",
2283 nested: {
2284 key4: "value4",
2285 }
2286 };
2287 doc1.merge(&doc2).ok();
2288 }
2289 let elapsed = start.elapsed();
2290 println!("100 merge operations: {:?}", elapsed);
2291 assert!(elapsed.as_millis() < 200);
2292 }
2293
2294 #[test]
2295 fn bench_fields_collection() {
2296 let doc = doc!{
2297 key1: "value1",
2298 key2: 2,
2299 nested: {
2300 key3: "value3",
2301 deep: {
2302 key4: "value4"
2303 }
2304 },
2305 array: [1, 2, 3]
2306 };
2307
2308 let start = std::time::Instant::now();
2309 for _ in 0..1000 {
2310 let _ = doc.fields();
2311 }
2312 let elapsed = start.elapsed();
2313 println!("1000 fields() calls: {:?}", elapsed);
2314 assert!(elapsed.as_millis() < 300);
2315 }
2316
2317 #[test]
2319 fn test_doc_macro_with_variables() {
2320 let name = "Alice";
2321 let age = 30;
2322 let city = String::from("NYC");
2323
2324 let doc = doc!{
2325 name: name,
2326 age: age,
2327 city: city
2328 };
2329
2330 assert_eq!(doc.get("name").unwrap(), Value::String("Alice".to_string()));
2331 assert_eq!(doc.get("age").unwrap(), Value::I32(30));
2332 assert_eq!(doc.get("city").unwrap(), Value::String("NYC".to_string()));
2333 }
2334
2335 #[test]
2336 fn test_doc_macro_with_expressions() {
2337 let base = 100;
2338 let multiplier = 2;
2339
2340 let doc = doc!{
2341 computed: (base * multiplier),
2342 sum: (10 + 20 + 30),
2343 concat: (format!("Hello {}", "World"))
2344 };
2345
2346 assert_eq!(doc.get("computed").unwrap(), Value::I32(200));
2347 assert_eq!(doc.get("sum").unwrap(), Value::I32(60));
2348 assert_eq!(doc.get("concat").unwrap(), Value::String("Hello World".to_string()));
2349 }
2350
2351 #[test]
2352 fn test_doc_macro_with_function_calls() {
2353 fn get_name() -> &'static str {
2354 "Bob"
2355 }
2356
2357 fn calculate_score() -> i32 {
2358 42
2359 }
2360
2361 let doc = doc!{
2362 name: (get_name()),
2363 score: (calculate_score()),
2364 length: ("hello".len())
2365 };
2366
2367 assert_eq!(doc.get("name").unwrap(), Value::String("Bob".to_string()));
2368 assert_eq!(doc.get("score").unwrap(), Value::I32(42));
2369 assert_eq!(doc.get("length").unwrap(), Value::U64(5));
2370 }
2371
2372 #[test]
2373 fn test_doc_macro_with_mixed_expressions_and_nested() {
2374 let user_name = "Charlie";
2375 let base_score = 50;
2376
2377 let doc = doc!{
2378 user: {
2379 name: user_name,
2380 score: (base_score * 2)
2381 },
2382 tags: ["admin", user_name],
2383 values: [1, (2 + 3), 6]
2384 };
2385
2386 assert_eq!(doc.get("user.name").unwrap(), Value::String("Charlie".to_string()));
2387 assert_eq!(doc.get("user.score").unwrap(), Value::I32(100));
2388
2389 let tags = doc.get("tags").unwrap();
2390 let tags_arr = tags.as_array().unwrap();
2391 assert_eq!(tags_arr[0], Value::String("admin".to_string()));
2392 assert_eq!(tags_arr[1], Value::String("Charlie".to_string()));
2393
2394 let values = doc.get("values").unwrap();
2395 let values_arr = values.as_array().unwrap();
2396 assert_eq!(values_arr[0], Value::I32(1));
2397 assert_eq!(values_arr[1], Value::I32(5));
2398 assert_eq!(values_arr[2], Value::I32(6));
2399 }
2400
2401 #[test]
2402 fn test_doc_macro_empty_new_syntax() {
2403 let doc = doc!{};
2404 assert!(doc.is_empty());
2405 }
2406
2407 #[test]
2410 fn test_merge_nested_document_in_place() {
2411 let mut doc1 = doc!{
2413 nested: {
2414 key1: "value1",
2415 inner: {
2416 a: 1
2417 }
2418 }
2419 };
2420
2421 let doc2 = doc!{
2422 nested: {
2423 key2: "value2",
2424 inner: {
2425 b: 2
2426 }
2427 }
2428 };
2429
2430 doc1.merge(&doc2).unwrap();
2431
2432 assert_eq!(doc1.get("nested.key1").unwrap(), Value::String("value1".to_string()));
2434 assert_eq!(doc1.get("nested.key2").unwrap(), Value::String("value2".to_string()));
2435 assert_eq!(doc1.get("nested.inner.a").unwrap(), Value::I32(1));
2436 assert_eq!(doc1.get("nested.inner.b").unwrap(), Value::I32(2));
2437 }
2438
2439 #[test]
2440 fn test_merge_document_overwrites_non_document() {
2441 let mut doc1 = doc!{
2443 field: "string_value"
2444 };
2445
2446 let doc2 = doc!{
2447 field: {
2448 nested: "value"
2449 }
2450 };
2451
2452 doc1.merge(&doc2).unwrap();
2453
2454 assert_eq!(doc1.get("field.nested").unwrap(), Value::String("value".to_string()));
2456 }
2457
2458 #[test]
2459 fn test_fields_with_prefix() {
2460 let doc = doc!{
2462 level1: {
2463 level2: {
2464 leaf: "value"
2465 }
2466 }
2467 };
2468
2469 let fields = doc.fields();
2470 assert!(fields.contains(&"level1.level2.leaf".to_string()));
2471 }
2472
2473 #[test]
2474 fn test_iterator_size_hint() {
2475 let doc = doc!{
2476 key1: "value1",
2477 key2: "value2",
2478 key3: "value3"
2479 };
2480
2481 let iter = doc.iter();
2482 let (lower, upper) = iter.size_hint();
2483
2484 assert_eq!(lower, 3);
2485 assert_eq!(upper, Some(3));
2486 }
2487
2488 #[test]
2489 fn test_remove_array_element_by_index() {
2490 let mut doc = doc!{
2491 items: [1, 2, 3, 4, 5]
2492 };
2493
2494 doc.remove("items.2").unwrap();
2496
2497 let items = doc.get("items").unwrap();
2498 let arr = items.as_array().unwrap();
2499 assert_eq!(arr.len(), 4);
2500 assert_eq!(arr[0], Value::I32(1));
2501 assert_eq!(arr[1], Value::I32(2));
2502 assert_eq!(arr[2], Value::I32(4)); assert_eq!(arr[3], Value::I32(5)); }
2505
2506 #[test]
2507 fn test_remove_nested_document_in_array() {
2508 let mut doc = doc!{
2509 items: [
2510 { name: "item1", value: 1 },
2511 { name: "item2", value: 2 },
2512 { name: "item3", value: 3 }
2513 ]
2514 };
2515
2516 doc.remove("items.1.value").unwrap();
2518
2519 let item1 = doc.get("items.1").unwrap();
2521 let item_doc = item1.as_document().unwrap();
2522 assert_eq!(item_doc.size(), 1);
2523 assert_eq!(item_doc.get("name").unwrap(), Value::String("item2".to_string()));
2524 assert_eq!(item_doc.get("value").unwrap(), Null);
2525 }
2526
2527 #[test]
2528 fn test_remove_entire_nested_document_in_array_when_empty() {
2529 let mut doc = doc!{
2530 items: [
2531 { only_field: "value" }
2532 ]
2533 };
2534
2535 doc.remove("items.0.only_field").unwrap();
2537
2538 let items = doc.get("items").unwrap();
2540 let arr = items.as_array().unwrap();
2541 assert_eq!(arr.len(), 0);
2542 }
2543
2544 #[test]
2545 fn test_remove_array_out_of_bounds() {
2546 let mut doc = doc!{
2547 items: [1, 2, 3]
2548 };
2549
2550 let result = doc.remove("items.10");
2552 assert!(result.is_err());
2553 }
2554
2555 #[test]
2556 fn test_remove_array_negative_index() {
2557 let mut doc = doc!{
2558 items: [1, 2, 3]
2559 };
2560
2561 let result = doc.remove("items.-1");
2563 assert!(result.is_err());
2564 }
2565
2566 #[test]
2567 fn test_remove_array_invalid_index_string() {
2568 let mut doc = doc!{
2569 items: [1, 2, 3]
2570 };
2571
2572 let result = doc.remove("items.abc");
2574 assert!(result.is_err());
2575 }
2576
2577 #[test]
2578 fn test_remove_non_existent_nested_path() {
2579 let mut doc = doc!{
2580 existing: "value"
2581 };
2582
2583 let result = doc.remove("non_existent.nested.path");
2585 assert!(result.is_ok());
2586 }
2587
2588 #[test]
2589 fn test_deep_put_creates_nested_structure() {
2590 let mut doc = doc!{};
2591
2592 doc.put("a.b.c.d", Value::String("deep".to_string())).unwrap();
2594
2595 assert_eq!(doc.get("a.b.c.d").unwrap(), Value::String("deep".to_string()));
2596 }
2597
2598 #[test]
2599 fn test_deep_put_into_existing_nested_document() {
2600 let mut doc = doc!{
2601 existing: {
2602 nested: {
2603 key1: "value1"
2604 }
2605 }
2606 };
2607
2608 doc.put("existing.nested.key2", Value::String("value2".to_string())).unwrap();
2610
2611 assert_eq!(doc.get("existing.nested.key1").unwrap(), Value::String("value1".to_string()));
2612 assert_eq!(doc.get("existing.nested.key2").unwrap(), Value::String("value2".to_string()));
2613 }
2614
2615 #[test]
2616 fn test_fields_skips_reserved_fields() {
2617 let mut doc = doc!{
2618 regular_field: "value"
2619 };
2620
2621 doc.put(DOC_ID, Value::NitriteId(NitriteId::new())).unwrap();
2623 doc.put(DOC_REVISION, Value::I32(1)).unwrap();
2624 doc.put(DOC_SOURCE, Value::String("source".to_string())).unwrap();
2625 doc.put(DOC_MODIFIED, Value::I64(12345)).unwrap();
2626
2627 let fields = doc.fields();
2628
2629 assert_eq!(fields.len(), 1);
2631 assert!(fields.contains(&"regular_field".to_string()));
2632 assert!(!fields.contains(&DOC_ID.to_string()));
2633 assert!(!fields.contains(&DOC_REVISION.to_string()));
2634 }
2635
2636 #[test]
2637 fn test_fields_skips_empty_keys() {
2638 let doc = doc!{
2639 valid_key: "value"
2640 };
2641
2642 let fields = doc.fields();
2646
2647 assert_eq!(fields.len(), 1);
2649 assert!(fields.contains(&"valid_key".to_string()));
2650 }
2651
2652 #[test]
2653 fn test_to_pretty_json_empty() {
2654 let doc = doc!{};
2655 let json = doc.to_pretty_json(0);
2656 assert_eq!(json, "{}");
2657 }
2658
2659 #[test]
2660 fn test_to_debug_string_empty() {
2661 let doc = doc!{};
2662 let debug = doc.to_debug_string(0);
2663 assert_eq!(debug, "{}");
2664 }
2665
2666 #[test]
2667 fn test_to_pretty_json_with_indent() {
2668 let doc = doc!{
2669 key: "value"
2670 };
2671 let json = doc.to_pretty_json(2);
2672 assert!(json.contains(" \"key\"")); }
2674
2675 #[test]
2676 fn test_to_debug_string_with_indent() {
2677 let doc = doc!{
2678 key: "value"
2679 };
2680 let debug = doc.to_debug_string(2);
2681 assert!(debug.contains(" \"key\"")); }
2683
2684 #[test]
2685 fn test_contains_field_embedded_path() {
2686 let mut doc = doc!{
2689 outer: "temp"
2690 };
2691
2692 let inner = doc!{
2694 inner: "value"
2695 };
2696 doc.put("outer", inner).unwrap();
2697
2698 assert!(doc.contains_field("outer"));
2700
2701 assert!(doc.contains_field("outer.inner"));
2703
2704 assert!(!doc.contains_field("outer.nonexistent"));
2706 assert!(!doc.contains_field("nonexistent.path"));
2707 }
2708
2709 #[test]
2710 fn test_deep_get_non_embedded_key() {
2711 let doc = doc!{
2714 name: "test"
2715 };
2716
2717 let result = doc.get("nonexistent");
2724 assert!(result.is_ok());
2725 assert_eq!(result.unwrap(), Value::Null);
2726 }
2727
2728
2729 #[cfg(test)]
2730 mod custom_separator_test {
2731 use super::*;
2732 use crate::nitrite_config::NitriteConfig;
2733
2734 #[test]
2735 #[cfg_attr(not(feature = "custom_separator"), ignore)]
2736 fn custom_separator_test_remove_array() {
2737 NitriteConfig::new().set_field_separator(":").expect("Failed to set separator");
2738 let mut doc = set_up();
2739 assert_eq!(
2740 doc.get("location:address:house")
2741 .unwrap()
2742 .as_array()
2743 .unwrap()
2744 .len(),
2745 3
2746 );
2747
2748 doc.remove("location:address:house:0").unwrap();
2749 assert_eq!(
2750 doc.get("location:address:house")
2751 .unwrap()
2752 .as_array()
2753 .unwrap()
2754 .len(),
2755 2
2756 );
2757
2758 assert_eq!(doc.get("obj_array").unwrap().as_array().unwrap().len(), 2);
2759 doc.remove("obj_array:0:value").unwrap();
2760 assert_eq!(doc.get("obj_array").unwrap().as_array().unwrap().len(), 1);
2761 assert_eq!(
2762 doc.get("obj_array:0")
2763 .unwrap()
2764 .as_document()
2765 .unwrap()
2766 .size(),
2767 1
2768 );
2769 }
2770
2771 #[test]
2772 #[cfg_attr(not(feature = "custom_separator"), ignore)]
2773 fn custom_separator_test_remove() {
2774 NitriteConfig::new().set_field_separator(":").expect("Failed to set separator");
2775 let mut doc = set_up();
2776 assert_eq!(
2777 doc.get("location:address")
2778 .unwrap()
2779 .as_document()
2780 .unwrap()
2781 .size(),
2782 4
2783 );
2784 doc.remove("location:address:line1").unwrap();
2785 assert_eq!(
2786 doc.get("location:address")
2787 .unwrap()
2788 .as_document()
2789 .unwrap()
2790 .size(),
2791 3
2792 );
2793 }
2794
2795 #[test]
2796 #[cfg_attr(not(feature = "custom_separator"), ignore)]
2797 fn custom_separator_test_get() {
2798 NitriteConfig::new().set_field_separator(":").expect("Failed to set separator");
2799
2800 let doc = set_up();
2801 let mut value = doc.get("").unwrap();
2802 assert_eq!(value, Null);
2803 value = doc.get("score").unwrap();
2804 assert_eq!(value, Value::I32(1034));
2805 value = doc.get("location:state").unwrap();
2806 assert_eq!(value, Value::String("NY".to_string()));
2807 value = doc.get("location:address").unwrap();
2808 assert_eq!(
2809 value,
2810 Value::Document(doc!{
2811 line1: "40",
2812 line2: "ABC Street",
2813 house: ["1", "2", "3"],
2814 zip: 10001,
2815 })
2816 );
2817 value = doc.get("location:address:line1").unwrap();
2818 assert_eq!(value, Value::String("40".to_string()));
2819 value = doc.get("location:address:line2").unwrap();
2820 assert_eq!(value, Value::String("ABC Street".to_string()));
2821 value = doc.get("location:address:house:0").unwrap();
2822 assert_eq!(value, Value::String("1".to_string()));
2823 value = doc.get("location:address:house:1").unwrap();
2824 assert_eq!(value, Value::String("2".to_string()));
2825 value = doc.get("location:address:house:2").unwrap();
2826 assert_eq!(value, Value::String("3".to_string()));
2827 value = doc.get("location:address:zip").unwrap();
2828 assert_eq!(value, Value::I32(10001));
2829
2830 value = doc.get("category:0").unwrap();
2831 assert_eq!(value, Value::String("food".to_string()));
2832 value = doc.get("category:1").unwrap();
2833 assert_eq!(value, Value::String("produce".to_string()));
2834 value = doc.get("category:2").unwrap();
2835 assert_eq!(value, Value::String("grocery".to_string()));
2836
2837 value = doc.get("obj_array:0").unwrap();
2838 assert_eq!(value, Value::Document(doc!{ value: 1 }));
2839 value = doc.get("obj_array:1").unwrap();
2840 assert_eq!(value, Value::Document(doc!{ value: 2 }));
2841 value = doc.get("obj_array:0:value").unwrap();
2842 assert_eq!(value, Value::I32(1));
2843 value = doc.get("obj_array:1:value").unwrap();
2844 assert_eq!(value, Value::I32(2));
2845
2846 value = doc.get("location:address:test").unwrap();
2847 assert_eq!(value, Null);
2848 assert!(doc.get("location:address:house:3").is_err());
2849 assert!(doc.get("location:address:house:-1").is_err());
2850 assert!(doc.get(":").is_err());
2851 assert!(doc.get("::").is_err());
2852 assert_eq!(doc.get("score:test").unwrap(), Null);
2853 }
2854
2855 #[test]
2856 #[cfg_attr(not(feature = "custom_separator"), ignore)]
2857 fn custom_separator_test_default_separator_fails() {
2858 NitriteConfig::new().set_field_separator(":").expect("Failed to set separator");
2859 let doc = set_up();
2860 let value = doc.get("location.address.house.0").unwrap();
2861 assert_eq!(value, Null);
2862
2863 let value = doc.get("location:address:house:0").unwrap();
2864 assert_eq!(value, Value::String("1".to_string()));
2865 }
2866 }
2867}