1use std::{cmp::Ordering, collections::{BTreeMap, HashMap, HashSet}, ops::Deref, sync::Arc};
18use crate::{lang::SError, IntoNodeRef, Library, SData, SDoc, SField, SFunc, SMutex, SNodeRef, SNum, SPrototype, SVal};
19
20
21#[derive(Default, Debug)]
22pub struct ObjectLibrary;
23impl ObjectLibrary {
24 pub fn operate(&self, pid: &str, doc: &mut SDoc, name: &str, obj: &SNodeRef, parameters: &mut Vec<SVal>) -> Result<SVal, SError> {
26 match name {
27 "len" => {
28 if let Some(node) = obj.node(&doc.graph) {
29 let refs = node.data_refs::<SField>(&doc.graph);
30 return Ok(SVal::Number(SNum::I64(refs.len() as i64)));
31 }
32 Ok(SVal::Number(SNum::I64(0)))
33 },
34 "at" => {
35 if parameters.len() == 1 {
36 match ¶meters[0] {
37 SVal::String(index) => {
38 if let Some(field) = SField::field(&doc.graph, &index, '.', Some(obj)) {
39 return Ok(field.value.clone());
40 } else if let Some(func) = SFunc::func_ref(&doc.graph, &index, '.', Some(obj)) {
41 return Ok(SVal::FnPtr(func));
42 }
43 return Ok(SVal::Null); },
45 SVal::Number(val) => {
46 let mut fields = SField::fields(&doc.graph, obj);
47 let index = val.int() as usize;
48 if index < fields.len() {
49 let field = fields.remove(index);
50 let value = field.value.clone();
51 let key = SVal::String(field.name.clone());
52 return Ok(SVal::Tuple(vec![key, value]));
53 }
54 },
55 _ => {}
56 }
57 }
58 if parameters.len() > 1 {
59 let mut array = Vec::new();
60 for param in parameters.drain(..) {
61 match param {
62 SVal::String(index) => {
63 if let Some(field) = SField::field(&doc.graph, &index, '.', Some(obj)) {
64 array.push(field.value.clone());
65 } else if let Some(func) = SFunc::func_ref(&doc.graph, &index, '.', Some(obj)) {
66 array.push(SVal::FnPtr(func));
67 }
68 },
69 SVal::Number(val) => {
70 let mut fields = SField::fields(&doc.graph, obj);
71 let index = val.int() as usize;
72 if index < fields.len() {
73 let field = fields.remove(index);
74 let value = field.value.clone();
75 let key = SVal::String(field.name.clone());
76 array.push(SVal::Tuple(vec![key, value]));
77 }
78 },
79 _ => {}
80 }
81 }
82 return Ok(SVal::Array(array));
83 }
84 Err(SError::obj(pid, &doc, "at", "invalid arguments - index must be a string or number"))
85 },
86 "reference" => {
87 if parameters.len() == 1 {
88 let field_path = parameters[0].to_string();
89 if let Some(field_ref) = SField::field_ref(&doc.graph, &field_path, '.', Some(obj)) {
90 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
91 self.operate(pid, doc, "removeField", obj, &mut vec![SVal::String(field.name.clone())])?;
92 }
93 SData::attach_existing(&mut doc.graph, obj, field_ref);
94 return Ok(SVal::Bool(true));
95 } else if let Some(field_ref) = SField::field_ref(&doc.graph, &field_path, '.', None) {
96 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
97 self.operate(pid, doc, "removeField", obj, &mut vec![SVal::String(field.name.clone())])?;
98 }
99 SData::attach_existing(&mut doc.graph, obj, field_ref);
100 return Ok(SVal::Bool(true));
101 } else if let Some(func) = SFunc::func_ref(&doc.graph, &field_path, '.', Some(obj)) {
102 SData::attach_existing(&mut doc.graph, obj, func);
103 return Ok(SVal::Bool(true));
104 } else if let Some(func) = SFunc::func_ref(&doc.graph, &field_path, '.', None) {
105 SData::attach_existing(&mut doc.graph, obj, func);
106 return Ok(SVal::Bool(true));
107 }
108 return Ok(SVal::Bool(false));
109 } else if parameters.len() == 2 {
110 match ¶meters[0] {
111 SVal::Object(context) => {
112 let field_path = parameters[1].to_string();
113 if let Some(field_ref) = SField::field_ref(&doc.graph, &field_path, '.', Some(&context)) {
114 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
115 self.operate(pid, doc, "removeField", obj, &mut vec![SVal::String(field.name.clone())])?;
116 }
117 SData::attach_existing(&mut doc.graph, obj, field_ref);
118 return Ok(SVal::Bool(true));
119 } else if let Some(func) = SFunc::func_ref(&doc.graph, &field_path, '.', Some(&context)) {
120 SData::attach_existing(&mut doc.graph, obj, func);
121 return Ok(SVal::Bool(true));
122 }
123 return Ok(SVal::Bool(false));
124 },
125 _ => {}
126 }
127 }
128 Err(SError::obj(pid, &doc, "reference", "path argument not found"))
129 },
130 "fields" => {
131 let fields = SField::fields(&doc.graph, obj);
132 let mut map = BTreeMap::new();
133 for field in fields {
134 let value = field.value.clone();
135 let key = SVal::String(field.name.clone());
136 map.insert(key, value);
137 }
138 Ok(SVal::Map(map))
139 },
140 "attributes" => {
141 if parameters.len() < 1 {
142 return Err(SError::obj(pid, &doc, "attributes", "invalid arguments - path not found"));
143 }
144 match ¶meters[0] {
145 SVal::String(index) => {
146 if let Some(field) = SField::field(&doc.graph, &index, '.', Some(obj)) {
147 let mut attrs = BTreeMap::new();
148 for (key, value) in &field.attributes {
149 attrs.insert(SVal::String(key.clone()), value.clone());
150 }
151 return Ok(SVal::Map(attrs));
152 } else if let Some(func_ref) = SFunc::func_ref(&doc.graph, &index, '.', Some(obj)) {
153 let mut attrs = BTreeMap::new();
154 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
155 for (key, value) in &func.attributes {
156 attrs.insert(SVal::String(key.clone()), value.clone());
157 }
158 }
159 return Ok(SVal::Map(attrs));
160 }
161 return Ok(SVal::Null); },
163 SVal::Boxed(val) => {
164 let val = val.lock().unwrap();
165 let val = val.deref();
166 match val {
167 SVal::String(index) => {
168 if let Some(field) = SField::field(&doc.graph, &index, '.', Some(obj)) {
169 let mut attrs = BTreeMap::new();
170 for (key, value) in &field.attributes {
171 attrs.insert(SVal::String(key.clone()), value.clone());
172 }
173 return Ok(SVal::Map(attrs));
174 } else if let Some(func_ref) = SFunc::func_ref(&doc.graph, &index, '.', Some(obj)) {
175 let mut attrs = BTreeMap::new();
176 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
177 for (key, value) in &func.attributes {
178 attrs.insert(SVal::String(key.clone()), value.clone());
179 }
180 }
181 return Ok(SVal::Map(attrs));
182 }
183 return Ok(SVal::Null); },
185 _ => {
186 Err(SError::obj(pid, &doc, "attributes", "invalid arguments - path must be a string"))
187 }
188 }
189 },
190 _ => {
191 Err(SError::obj(pid, &doc, "attributes", "invalid arguments - path must be a string"))
192 }
193 }
194 },
195 "funcs" |
196 "functions" => {
197 let funcs = SFunc::func_refs(&doc.graph, obj);
198 let mut map = BTreeMap::new();
199 for func_ref in funcs {
200 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
201 let value = SVal::FnPtr(func_ref);
202 let key = SVal::String(func.name.clone());
203 map.insert(key, value);
204 }
205 }
206 Ok(SVal::Map(map))
207 },
208 "keys" => {
209 let fields = SField::fields(&doc.graph, obj);
210 let mut array = Vec::new();
211 for field in fields {
212 array.push(SVal::String(field.name.clone()));
213 }
214 Ok(SVal::Array(array))
215 },
216 "values" => {
217 let fields = SField::fields(&doc.graph, obj);
218 let mut array = Vec::new();
219 for field in fields {
220 array.push(field.value.clone());
221 }
222 Ok(SVal::Array(array))
223 },
224 "unbox" => {
227 if parameters.len() < 1 {
228 return Err(SError::obj(pid, &doc, "unbox", "invalid arguments - expecing a string path to a field that should be unboxed on this object"));
229 }
230 let path = parameters[0].to_string();
231 let mut value = None;
232 if parameters.len() > 1 {
233 value = Some(parameters.pop().unwrap());
234 }
235
236 if let Some(field_ref) = SField::field_ref(&doc.graph, &path, '.', Some(obj)) {
238 if !doc.perms.can_write_field(&doc.graph, &field_ref, Some(obj)) {
239 return Ok(SVal::Bool(false));
240 }
241 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, &field_ref) {
242 if let Some(value) = value {
243 field.value = value.unbox();
244 } else {
245 field.value.unbox_ref();
246 }
247 return Ok(SVal::Bool(true));
248 }
249 return Ok(SVal::Bool(false));
250 }
251 if let Some(value) = value {
252 let mut path = path.split('.').collect::<Vec<&str>>();
254 let name = path.pop().unwrap().to_string();
255
256 let mut fref = obj.clone();
258 if path.len() > 0 {
259 fref = doc.graph.ensure_nodes(&path.join("/"), '/', true, Some(obj.clone()));
260 }
261
262 let field = SField::new(&name, value.unbox());
264 SData::insert_new(&mut doc.graph, &fref, Box::new(field));
265 return Ok(SVal::Bool(true));
266 }
267 Ok(SVal::Bool(false))
268 },
269 "box" => {
272 if parameters.len() < 1 {
273 return Err(SError::obj(pid, &doc, "box", "invalid arguments - expecing a string path to a field that should be boxed on this object"));
274 }
275 let path = parameters[0].to_string();
276 let mut value = None;
277 if parameters.len() > 1 {
278 value = Some(parameters.pop().unwrap());
279 }
280
281 if let Some(field_ref) = SField::field_ref(&doc.graph, &path, '.', Some(obj)) {
283 if !doc.perms.can_write_field(&doc.graph, &field_ref, Some(obj)) {
284 return Ok(SVal::Bool(false));
285 }
286 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, &field_ref) {
287 if let Some(value) = value {
288 field.value = value.to_box();
289 } else {
290 field.value.to_box_ref();
291 }
292 return Ok(SVal::Bool(true));
293 }
294 return Ok(SVal::Bool(false));
295 }
296
297 let mut path = path.split('.').collect::<Vec<&str>>();
299 let name = path.pop().unwrap().to_string();
300
301 let mut fref = obj.clone();
303 if path.len() > 0 {
304 fref = doc.graph.ensure_nodes(&path.join("/"), '/', true, Some(obj.clone()));
305 }
306
307 let mut field = SField::new(&name, SVal::Null.to_box());
309 if let Some(value) = value {
310 field.value = value.to_box();
311 }
312 SData::insert_new(&mut doc.graph, &fref, Box::new(field));
313 Ok(SVal::Bool(true))
314 },
315 "set" => {
316 if parameters.len() == 2 {
317 let value = parameters.pop().unwrap();
318 let name = parameters.pop().unwrap().to_string();
319
320 if let Some(field_ref) = SField::field_ref(&doc.graph, &name, '.', Some(obj)) {
322 if !doc.perms.can_write_field(&doc.graph, &field_ref, Some(obj)) {
323 return Ok(SVal::Bool(false));
324 }
325 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, &field_ref) {
326 field.value = value;
327 return Ok(SVal::Bool(true));
328 }
329 return Ok(SVal::Bool(false));
330 }
331
332 let mut path = name.split('.').collect::<Vec<&str>>();
334 let name = path.pop().unwrap().to_string();
335
336 let mut fref = obj.clone();
338 if path.len() > 0 {
339 fref = doc.graph.ensure_nodes(&path.join("/"), '/', true, Some(obj.clone()));
340 }
341
342 let field = SField::new(&name, value);
344 SData::insert_new(&mut doc.graph, &fref, Box::new(field));
345 return Ok(SVal::Bool(true));
346 }
347 Err(SError::obj(pid, &doc, "set", "invalid arguments - requires a name and value to set a field"))
348 },
349 "mapFields" => {
352 if parameters.len() < 1 {
353 return Err(SError::obj(pid, &doc, "mapFields", "invalid arguments - requires a map argument"));
354 }
355 match ¶meters[0] {
356 SVal::Map(map) => {
357 let mut mapped_values = BTreeMap::new();
358 for (k, v) in map {
359 let res = self.operate(pid, doc, "renameField", obj, &mut vec![k.clone(), v.clone()])?;
360 if res.truthy() {
361 mapped_values.insert(k.clone(), v.clone());
362 }
363 }
364 Ok(SVal::Map(mapped_values))
365 },
366 SVal::Boxed(val) => {
367 let val = val.lock().unwrap();
368 let val = val.deref();
369 match val {
370 SVal::Map(map) => {
371 let mut mapped_values = BTreeMap::new();
372 for (k, v) in map {
373 let res = self.operate(pid, doc, "renameField", obj, &mut vec![k.clone(), v.clone()])?;
374 if res.truthy() {
375 mapped_values.insert(k.clone(), v.clone());
376 }
377 }
378 Ok(SVal::Map(mapped_values))
379 },
380 _ => {
381 Err(SError::obj(pid, &doc, "mapFields", "invalid arguments - map argument not found"))
382 }
383 }
384 },
385 _ => {
386 Err(SError::obj(pid, &doc, "mapFields", "invalid arguments - map argument not found"))
387 }
388 }
389 },
390 "moveField" |
393 "renameField" => {
394 if parameters.len() < 2 {
395 return Err(SError::obj(pid, &doc, "moveField", "invalid arguments - requires two paths, a source and a destination"));
396 }
397 let dest = parameters.pop().unwrap().owned_to_string();
398 let source = parameters.pop().unwrap().owned_to_string();
399
400 if let Some(field_ref) = SField::field_ref(&doc.graph, &source, '.', Some(obj)) {
401 if !doc.perms.can_write_field(&doc.graph, &field_ref, Some(obj)) {
402 return Ok(SVal::Bool(false));
403 }
404
405 if let Some(existing_ref) = SField::field_ref(&doc.graph, &dest, '.', Some(obj)) {
407 let clone;
409 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
410 clone = field.clone();
411 } else {
412 return Ok(SVal::Bool(false));
413 }
414
415 doc.graph.remove_data(&field_ref, None);
417
418 if let Some(existing) = SData::get_mut::<SField>(&mut doc.graph, existing_ref) {
419 existing.merge(&clone)?;
420 }
421 } else {
422 let mut dest_path = dest.split('.').collect::<Vec<&str>>();
424 let new_field_name = dest_path.pop().unwrap();
425
426 if dest_path.len() > 0 {
428 let mut clone;
430 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
431 clone = field.clone();
432 } else {
433 return Ok(SVal::Bool(false));
434 }
435
436 doc.graph.remove_data(&field_ref, None);
438
439 clone.name = new_field_name.to_owned();
440 let dest_node_path = dest_path.join(".");
441 let dest_ref = doc.graph.ensure_nodes(&dest_node_path, '.', true, Some(obj.clone()));
442
443 match &clone.value {
445 SVal::Object(nref) => {
446 doc.graph.rename_node(nref, new_field_name);
447
448 let id_path: HashSet<String> = HashSet::from_iter(nref.id_path(&doc.graph).into_iter());
449 if !id_path.contains(&dest_ref.id) && !dest_ref.is_child_of(&doc.graph, &nref) {
450 doc.graph.move_node(nref, &dest_ref);
451 }
452 },
453 _ => {}
454 }
455
456 SData::insert_new_id(&mut doc.graph, &dest_ref, Box::new(clone), &field_ref.id); } else {
458 let mut rename_node = None;
460 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, field_ref) {
461 field.name = new_field_name.to_owned();
462
463 match &field.value {
465 SVal::Object(nref) => {
466 rename_node = Some(nref.clone());
467 },
468 _ => {}
469 }
470 }
471 if let Some(rename_node) = rename_node {
472 doc.graph.rename_node(&rename_node, new_field_name);
473 }
474 }
475 }
476 return Ok(SVal::Bool(true));
477 }
478 Ok(SVal::Bool(false))
479 },
480 "removeField" => {
483 if parameters.len() < 1 {
484 return Err(SError::obj(pid, &doc, "removeField", "invalid arguments - field path not found"));
485 }
486 let mut remove_obj = false;
487 if parameters.len() > 1 {
488 remove_obj = parameters.pop().unwrap().truthy();
489 }
490 let path = parameters.pop().unwrap().to_string();
491
492 if let Some(field_ref) = SField::field_ref(&doc.graph, &path, '.', Some(obj)) {
493 if !doc.perms.can_write_field(&doc.graph, &field_ref, Some(obj)) {
494 return Ok(SVal::Bool(false));
495 }
496 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
497 if remove_obj && field.value.is_object() {
498 match field.value.clone().unbox() {
499 SVal::Object(nref) => {
500 doc.types.drop_types_for(&nref, &doc.graph);
501 doc.graph.remove_node(nref);
502 },
503 _ => {}
504 }
505 }
506 }
507
508 if path.contains('.') {
509 doc.graph.remove_data(field_ref, None);
511 } else {
512 doc.graph.remove_data(field_ref, Some(obj));
514 }
515 return Ok(SVal::Bool(true));
516 }
517 Ok(SVal::Bool(false))
518 },
519 "removeFunc" => {
522 if parameters.len() < 1 {
523 return Err(SError::obj(pid, &doc, "removeFunc", "invalid arguments - func path not found"));
524 }
525 let path = parameters.pop().unwrap().to_string();
526
527 if let Some(func_ref) = SFunc::func_ref(&doc.graph, &path, '.', Some(obj)) {
528 if !doc.perms.can_write_func(&doc.graph, &func_ref, Some(obj)) {
529 return Ok(SVal::Bool(false));
530 }
531 if path.contains('.') {
532 doc.graph.remove_data(func_ref, None);
533 } else {
534 doc.graph.remove_data(func_ref, Some(obj));
535 }
536 return Ok(SVal::Bool(true));
537 }
538 Ok(SVal::Bool(false))
539 },
540 "name" => {
541 if let Some(node) = obj.node(&doc.graph) {
542 return Ok(SVal::String(node.name.clone()));
543 }
544 Err(SError::obj(pid, &doc, "name", "could not find object"))
545 },
546 "id" => {
547 Ok(SVal::String(obj.id.clone()))
548 },
549 "parent" => {
550 if let Some(node) = obj.node(&doc.graph) {
551 if let Some(parent) = &node.parent {
552 return Ok(SVal::Object(parent.clone()));
553 }
554 }
555 Ok(SVal::Null)
556 },
557 "prototype" => {
559 if let Some(prototype) = SPrototype::get(&doc.graph, obj) {
560 return Ok(SVal::Object(prototype.node_ref()));
561 }
562 Ok(SVal::Null)
563 },
564 "setPrototype" => {
566 if parameters.len() < 1 {
567 return Err(SError::obj(pid, &doc, "setPrototype", "invalid arguments - object prototype not found"));
568 }
569 match ¶meters[0] {
570 SVal::Object(nref) => {
571 if let Some(prototype_ref) = SPrototype::get_ref(&doc.graph, obj) {
572 if let Some(prototype) = SData::get_mut::<SPrototype>(&mut doc.graph, prototype_ref) {
573 prototype.prototype = nref.id.clone();
574 }
575 } else {
576 let prototype = SPrototype::new(nref);
577 SData::insert_new(&mut doc.graph, obj, Box::new(prototype));
578 }
579 return Ok(SVal::Void);
580 },
581 SVal::Boxed(val) => {
582 let val = val.lock().unwrap();
583 let val = val.deref();
584 match val {
585 SVal::Object(nref) => {
586 if let Some(prototype_ref) = SPrototype::get_ref(&doc.graph, obj) {
587 if let Some(prototype) = SData::get_mut::<SPrototype>(&mut doc.graph, prototype_ref) {
588 prototype.prototype = nref.id.clone();
589 }
590 } else {
591 let prototype = SPrototype::new(nref);
592 SData::insert_new(&mut doc.graph, obj, Box::new(prototype));
593 }
594 return Ok(SVal::Void);
595 },
596 _ => {}
597 }
598 },
599 _ => {}
600 }
601 Err(SError::obj(pid, &doc, "setPrototype", "invalid arguments - object prototype not found"))
602 },
603 "prototypeAttributes" => {
605 if let Some(prototype) = SPrototype::get(&doc.graph, obj) {
606 let attributes = prototype.attributes(&doc);
607 let mut map = BTreeMap::new();
608 for (k, v) in attributes {
609 map.insert(SVal::String(k), v);
610 }
611 return Ok(SVal::Map(map));
612 }
613 Ok(SVal::Null)
614 }
615 "root" => {
618 if let Some(root) = obj.root(&doc.graph) {
619 return Ok(SVal::Object(root.node_ref()));
620 }
621 Ok(SVal::Null)
622 },
623 "isRoot" => {
625 if let Some(node) = obj.node(&doc.graph) {
626 Ok(SVal::Bool(node.parent.is_none()))
627 } else {
628 Ok(SVal::Bool(true)) }
630 },
631 "path" => {
632 Ok(SVal::String(obj.path(&doc.graph).replace('/', ".")))
633 },
634 "children" => {
635 if let Some(node) = obj.node(&doc.graph) {
636 let mut children = Vec::new();
637 for child in &node.children {
638 children.push(SVal::Object(child.clone()));
639 }
640 return Ok(SVal::Array(children));
641 }
642 Ok(SVal::Array(vec![]))
643 },
644 "typename" => {
645 let typename = SVal::Object(obj.clone()).type_name(&doc.graph);
646 Ok(SVal::String(typename))
647 },
648 "typestack" => {
649 let typestack = SVal::Object(obj.clone()).type_stack(&doc.graph);
650 Ok(SVal::Array(typestack.into_iter().map(|x| SVal::String(x)).collect()))
651 },
652 "instanceOf" => {
653 if parameters.len() < 1 {
654 return Err(SError::obj(pid, &doc, "instanceOf", "invalid arguments - type string not found"));
655 }
656 let iof = SVal::Object(obj.clone()).instance_of(&doc.graph, ¶meters[0].to_string());
657 Ok(SVal::Bool(iof))
658 },
659 "upcast" => {
660 if let Some(prototype_ref) = SPrototype::get_ref(&doc.graph, obj) {
661 let mut parent_id = String::default();
662 if let Some(prototype) = SData::get::<SPrototype>(&doc.graph, &prototype_ref) {
663 if let Some(node) = prototype.node_ref().node(&doc.graph) {
664 if let Some(parent_ref) = &node.parent {
665 if let Some(parent) = parent_ref.node(&doc.graph) {
666 if parent.name != "__stof__" && parent.name != "prototypes" {
667 parent_id = parent.id.clone();
668 }
669 }
670 }
671 }
672 }
673 if parent_id.len() > 0 {
674 if let Some(prototype) = SData::get_mut::<SPrototype>(&mut doc.graph, prototype_ref) {
675 prototype.prototype = parent_id;
676 return Ok(SVal::Bool(true));
677 }
678 }
679 }
680 Ok(SVal::Bool(false))
681 },
682 "removePrototype" => {
684 if let Some(prototype) = SPrototype::get_ref(&doc.graph, obj) {
685 doc.graph.remove_data(prototype, Some(obj));
686 return Ok(SVal::Bool(true));
687 }
688 Ok(SVal::Bool(false))
689 },
690
691 "dbg_dump" => {
693 if let Some(node) = obj.node(&doc.graph) {
694 let dump = node.dump(&doc.graph, 0, true);
695 println!("{dump}");
696 }
697 Ok(SVal::Void)
698 },
699
700 "search" => {
707 if parameters.len() < 1 {
708 return Err(SError::obj(pid, &doc, "search", "invalid arguments - field name not found"));
709 }
710 let up = self.operate(pid, doc, "searchUp", obj, parameters)?;
711
712 let mut down_parameters = vec![parameters[0].clone(), SVal::Number(SNum::I64(0))];
713 if parameters.len() > 2 { down_parameters.push(parameters[2].clone()); }
714 let down = self.operate(pid, doc, "searchDown", obj, &mut down_parameters)?;
715
716 if !up.is_empty() && !down.is_empty() {
717 match up {
718 SVal::Tuple(up) => {
719 match down {
720 SVal::Tuple(down) => {
721 let down_lte_up = down.last().unwrap().lte(up.last().unwrap())?;
722 if down_lte_up.truthy() {
723 return Ok(SVal::Tuple(down));
725 } else {
726 return Ok(SVal::Tuple(up));
728 }
729 },
730 _ => {}
731 }
732 },
733 _ => {}
734 }
735 } else if !up.is_empty() {
736 return Ok(up);
737 } else if !down.is_empty() {
738 return Ok(down);
739 }
740 Ok(SVal::Null)
741 },
742
743 "searchUp" => {
747 if parameters.len() < 1 {
748 return Err(SError::obj(pid, &doc, "searchUp", "invalid arguments - field name not found"));
749 }
750 let mut obj_ignore_set = HashSet::new();
751 if parameters.len() > 2 {
752 match ¶meters[2] {
753 SVal::Array(vals) => {
754 for v in vals {
755 match v {
756 SVal::Object(nref) => {
757 obj_ignore_set.insert(nref.id.clone());
758 },
759 _ => {}
760 }
761 }
762 },
763 _ => {}
764 }
765 }
766
767 let field_name = parameters[0].to_string();
768
769 if !obj_ignore_set.contains(&obj.id) {
770 if let Some(field_ref) = SField::field_ref(&doc.graph, &field_name, '.', Some(obj)) {
771 if doc.perms.can_read_field(&doc.graph, &field_ref, Some(obj)) {
772 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
773 return Ok(SVal::Tuple(vec![field.value.clone(), SVal::Number(SNum::I64(0))]));
774 }
775 }
776 }
777 }
778 obj_ignore_set.insert(obj.id.clone()); let mut allow_parent_children = true;
782 let mut child_finds = Vec::new();
783 if parameters.len() > 1 {
784 allow_parent_children = parameters[1].truthy();
785 }
786
787 let mut parent = None;
788 let mut parent_field = None;
789 let mut parent_field_ref = None;
790 if let Some(node) = obj.node(&doc.graph) {
791 parent = node.parent.clone();
792 }
793 let mut parent_distance = 1;
794 while parent.is_some() {
795 if let Some(parent) = &parent {
796 if !obj_ignore_set.contains(&parent.id) {
797 if let Some(field_ref) = SField::field_ref(&doc.graph, &field_name, '.', Some(parent)) {
798 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
799 parent_field = Some(field);
800 }
801 parent_field_ref = Some(field_ref);
802 break;
803 }
804 obj_ignore_set.insert(parent.id.clone()); }
806 }
807 if allow_parent_children {
808 let mut params = vec![parameters[0].clone(), SVal::Number(SNum::I64(parent_distance))];
809 if obj_ignore_set.len() > 0 {
810 let vals = obj_ignore_set.iter().map(|id| SVal::Object(SNodeRef::new(id))).collect();
811 params.push(SVal::Array(vals));
812 }
813 let val = self.operate(pid, doc, "searchDown", &parent.clone().unwrap(), &mut params)?;
814 if !val.is_empty() {
815 child_finds.push(val);
816 }
817 }
818
819 if let Some(node) = parent.unwrap().node(&doc.graph) {
820 parent = node.parent.clone();
821 } else {
822 parent = None;
823 }
824 parent_distance += 1;
825 }
826
827 if child_finds.len() > 0 {
829 child_finds.sort_by(|a, b| {
830 match a {
831 SVal::Tuple(a) => {
832 match b {
833 SVal::Tuple(b) => {
834 let a_lt = a.last().unwrap().lt(b.last().unwrap()).unwrap();
835 if a_lt.truthy() {
836 return Ordering::Less;
837 }
838 let a_gt = a.last().unwrap().gt(b.last().unwrap()).unwrap();
839 if a_gt.truthy() {
840 return Ordering::Greater;
841 }
842 },
843 _ => {}
844 }
845 },
846 _ => {}
847 }
848 Ordering::Equal
849 });
850 }
851
852 if let Some(field) = parent_field { if child_finds.len() > 0 {
854 let first_child = child_finds.remove(0);
856 let mut return_child = false;
857 match &first_child {
858 SVal::Tuple(tup) => {
859 match &tup.last().unwrap() {
860 SVal::Number(num) => {
861 let dist = num.int();
862 if dist < parent_distance {
863 return_child = true;
864 }
865 },
866 _ => {}
867 }
868 },
869 _ => {}
870 }
871 if return_child {
872 return Ok(first_child);
873 }
874 }
875 if let Some(parent_ref) = parent_field_ref {
876 if doc.perms.can_read_field(&doc.graph, &parent_ref, Some(obj)) {
877 return Ok(SVal::Tuple(vec![field.value.clone(), SVal::Number(SNum::I64(parent_distance))]));
878 }
879 }
880 } else if child_finds.len() > 0 {
881 return Ok(child_finds.remove(0));
882 }
883 Ok(SVal::Null)
884 },
885
886 "searchDown" => {
890 if parameters.len() < 1 {
891 return Err(SError::obj(pid, &doc, "searchDown", "invalid arguments - field name not found"));
892 }
893
894 let mut current_distance = 0;
895 if parameters.len() > 1 {
896 match ¶meters[1] {
897 SVal::Number(num) => {
898 current_distance = num.int();
899 },
900 _ => {}
901 }
902 }
903 let mut obj_ignore_set = HashSet::new();
904 if parameters.len() > 2 {
905 match ¶meters[2] {
906 SVal::Array(vals) => {
907 for v in vals {
908 match v {
909 SVal::Object(nref) => {
910 obj_ignore_set.insert(nref.id.clone());
911 },
912 _ => {}
913 }
914 }
915 },
916 _ => {}
917 }
918 }
919
920 let field_name = parameters[0].to_string();
921
922 if !obj_ignore_set.contains(&obj.id) {
923 if let Some(field_ref) = SField::field_ref(&doc.graph, &field_name, '.', Some(obj)) {
924 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
925 if doc.perms.can_read_field(&doc.graph, &field_ref, Some(obj)) {
926 return Ok(SVal::Tuple(vec![field.value.clone(), SVal::Number(SNum::I64(current_distance))]));
927 }
928 }
929 }
930 }
931 let children;
932 if let Some(node) = obj.node(&doc.graph) {
933 children = node.children.clone();
934 } else {
935 return Ok(SVal::Null); }
937 let mut params = vec![parameters[0].clone(), SVal::Number(SNum::I64(current_distance + 1))];
938 if obj_ignore_set.len() > 0 {
939 params.push(parameters[2].clone());
940 }
941 let mut child_finds = Vec::new();
942 for child in children {
943 let val = self.operate(pid, doc, "searchDown", &child, &mut params)?;
944 if !val.is_empty() {
945 child_finds.push(val);
946 }
947 }
948 if child_finds.len() > 0 {
949 child_finds.sort_by(|a, b| {
950 match a {
951 SVal::Tuple(a) => {
952 match b {
953 SVal::Tuple(b) => {
954 let a_lt = a.last().unwrap().lt(b.last().unwrap()).unwrap();
955 if a_lt.truthy() {
956 return Ordering::Less;
957 }
958 let a_gt = a.last().unwrap().gt(b.last().unwrap()).unwrap();
959 if a_gt.truthy() {
960 return Ordering::Greater;
961 }
962 },
963 _ => {}
964 }
965 },
966 _ => {}
967 }
968 Ordering::Equal
969 });
970 return Ok(child_finds.remove(0));
971 }
972 Ok(SVal::Null)
973 },
974
975 "schemafy" => {
982 if parameters.len() < 1 {
983 return Err(SError::obj(pid, &doc, "schemafy", "invalid arguments - expecting a target object to apply this schema on"));
984 }
985
986 let target;
987 match ¶meters[0] {
988 SVal::Object(nref) => target = nref.clone(),
989 SVal::Boxed(val) => {
990 let val = val.lock().unwrap();
991 let val = val.deref();
992 match val {
993 SVal::Object(nref) => target = nref.clone(),
994 _ => {
995 return Err(SError::obj(pid, &doc, "schemafy", "invalid arguments - expecting a target object to apply this schema on"));
996 }
997 }
998 },
999 _ => {
1000 return Err(SError::obj(pid, &doc, "schemafy", "invalid arguments - expecting a target object to apply this schema on"));
1001 }
1002 }
1003
1004 let mut remove_invalid_fields = true;
1005 if parameters.len() > 1 {
1006 remove_invalid_fields = parameters[1].truthy();
1007 }
1008
1009 let mut remove_undefined_fields = false;
1010 if parameters.len() > 2 {
1011 remove_undefined_fields = parameters[2].truthy();
1012 }
1013
1014 let mut schema_fields: HashMap<String, SVal> = HashMap::new();
1017 let mut schema_field_names = HashSet::new();
1018 for schema_field in SField::fields(&doc.graph, obj) {
1019 if let Some(schema_val) = schema_field.attributes.get("schema") {
1020 schema_fields.insert(schema_field.name.clone(), schema_val.clone());
1021 }
1022 if remove_undefined_fields {
1023 schema_field_names.insert(schema_field.name.clone());
1024 }
1025 }
1026
1027 let mut valid = true;
1029 for (field, value) in schema_fields {
1030 if !self.schemafy_field(doc, pid, &obj, &target, &field, value, remove_invalid_fields, remove_undefined_fields) {
1031 valid = false;
1032 if remove_invalid_fields {
1033 self.operate(pid, doc, "removeField", &target, &mut vec![SVal::String(field), SVal::Bool(true)])?;
1035 }
1036 }
1037 }
1038
1039 if remove_undefined_fields {
1042 let mut to_remove = Vec::new();
1043 for field_ref in SField::field_refs(&doc.graph, &target) {
1044 if let Some(field) = SData::get::<SField>(&doc.graph, &field_ref) {
1045 if !schema_field_names.contains(&field.name) {
1046 to_remove.push(field.name.clone());
1047 }
1048 }
1049 }
1050 for field_name in to_remove {
1051 self.operate(pid, doc, "removeField", &target, &mut vec![SVal::String(field_name), SVal::Bool(true)])?;
1053 }
1054 }
1055 Ok(SVal::Bool(valid))
1056 },
1057
1058 "exec" => {
1069 let mut tasks = Vec::new();
1071 for field in SField::fields(&doc.graph, obj) {
1072 if let Some(attr) = field.attributes.get("run") {
1073 let mut order = -2;
1074 match &attr {
1075 SVal::Number(num) => {
1076 order = num.int();
1077 },
1078 SVal::Boxed(val) => {
1079 let val = val.lock().unwrap();
1080 let val = val.deref();
1081 match val {
1082 SVal::Number(num) => {
1083 order = num.int();
1084 },
1085 _ => {}
1086 }
1087 },
1088 _ => {}
1089 }
1090 match &field.value {
1091 SVal::Object(other) => {
1092 tasks.push((order, SVal::Object(other.clone())));
1093 },
1094 SVal::Array(_) => {
1095 tasks.push((order, field.value.clone()));
1096 },
1097 SVal::Set(_) => {
1098 tasks.push((order, field.value.clone()));
1099 },
1100 SVal::Map(_) => {
1101 tasks.push((order, field.value.clone()));
1102 },
1103 SVal::Boxed(val) => {
1104 let val = val.lock().unwrap();
1105 let val = val.deref();
1106 match val {
1107 SVal::Object(other) => {
1108 tasks.push((order, SVal::Object(other.clone())));
1109 },
1110 SVal::Array(_) => {
1111 tasks.push((order, val.clone()));
1112 },
1113 SVal::Set(_) => {
1114 tasks.push((order, val.clone()));
1115 },
1116 SVal::Map(_) => {
1117 tasks.push((order, val.clone()));
1118 },
1119 _ => {}
1120 }
1121 },
1122 _ => {}
1123 }
1124 }
1125 }
1126
1127 let mut func_names = HashSet::new();
1128 for func_ref in SFunc::func_refs(&doc.graph, obj) {
1129 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
1130 func_names.insert(func.name.clone());
1131 if let Some(attr) = func.attributes.get("run") {
1132 let mut order = -1;
1133 match &attr {
1134 SVal::Number(num) => {
1135 order = num.int();
1136 },
1137 SVal::Boxed(val) => {
1138 let val = val.lock().unwrap();
1139 let val = val.deref();
1140 match val {
1141 SVal::Number(num) => {
1142 order = num.int();
1143 },
1144 _ => {}
1145 }
1146 },
1147 _ => {}
1148 }
1149 tasks.push((order, SVal::FnPtr(func_ref)));
1150 }
1151 }
1152 }
1153 for nref in SPrototype::get_stack(&doc.graph, obj) {
1154 for func_ref in SFunc::func_refs(&doc.graph, &nref) {
1155 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
1156 if !func_names.contains(&func.name) {
1157 func_names.insert(func.name.clone());
1158 if let Some(attr) = func.attributes.get("run") {
1159 let mut order = -1;
1160 match &attr {
1161 SVal::Number(num) => {
1162 order = num.int();
1163 },
1164 SVal::Boxed(val) => {
1165 let val = val.lock().unwrap();
1166 let val = val.deref();
1167 match val {
1168 SVal::Number(num) => {
1169 order = num.int();
1170 },
1171 _ => {}
1172 }
1173 },
1174 _ => {}
1175 }
1176 tasks.push((order, SVal::FnPtr(func_ref)));
1177 }
1178 }
1179 }
1180 }
1181 }
1182
1183 tasks.sort_by(|a, b| a.0.cmp(&b.0));
1184 doc.push_self(pid, obj.clone());
1185 for task in tasks {
1186 self.exec_val(task.1, doc, pid, parameters)?;
1187 }
1188 doc.pop_self(pid);
1189
1190 Ok(SVal::Void)
1191 },
1192
1193 "shallowCopy" => {
1199 if parameters.len() < 1 {
1200 return Err(SError::obj(pid, &doc, "shallowCopy", "invalid arguments - object to copy not found"));
1201 }
1202 match ¶meters[0] {
1203 SVal::Object(to_copy) => {
1204 let data;
1205 if let Some(copy_node) = to_copy.node(&doc.graph) {
1206 data = copy_node.data.clone();
1207 } else {
1208 return Err(SError::obj(pid, &doc, "shallowCopy", "invalid arguments - object to copy does not exist"));
1209 }
1210 for data in data {
1211 doc.graph.put_data_ref(obj, data);
1212 }
1213 Ok(SVal::Void)
1214 },
1215 SVal::Boxed(val) => {
1216 let val = val.lock().unwrap();
1217 let val = val.deref();
1218 match val {
1219 SVal::Object(to_copy) => {
1220 let data;
1221 if let Some(copy_node) = to_copy.node(&doc.graph) {
1222 data = copy_node.data.clone();
1223 } else {
1224 return Err(SError::obj(pid, &doc, "shallowCopy", "invalid arguments - object to copy does not exist"));
1225 }
1226 for data in data {
1227 doc.graph.put_data_ref(obj, data);
1228 }
1229 Ok(SVal::Void)
1230 },
1231 _ => {
1232 Err(SError::obj(pid, &doc, "shallowCopy", "invalid arguments - object to copy not found"))
1233 }
1234 }
1235 },
1236 _ => {
1237 Err(SError::obj(pid, &doc, "shallowCopy", "invalid arguments - object to copy not found"))
1238 }
1239 }
1240 },
1241 "deepCopyFields" => {
1245 if parameters.len() < 1 {
1246 return Err(SError::obj(pid, &doc, "deepCopyFields", "invalid arguments - object to copy not found"));
1247 }
1248 match ¶meters[0] {
1249 SVal::Object(to_copy) => {
1250 let mut fields = Vec::new();
1251 for field in SField::fields(&doc.graph, to_copy) {
1252 fields.push(field.clone());
1253 }
1254 for field in fields {
1255 if field.is_object() {
1256 match field.value.clone().unbox() {
1257 SVal::Object(nref) => {
1258 let deep_copy = SField::new_object(&mut doc.graph, &field.name, obj);
1259 let to_copy = SVal::Object(nref);
1260 self.operate(pid, doc, "deepCopyFields", &deep_copy, &mut vec![to_copy])?;
1261 },
1262 _ => {}
1263 }
1264 } else {
1265 SData::insert_new(&mut doc.graph, obj, Box::new(field));
1266 }
1267 }
1268 Ok(SVal::Void)
1269 },
1270 SVal::Boxed(val) => {
1271 let val = val.lock().unwrap();
1272 let val = val.deref();
1273 match val {
1274 SVal::Object(to_copy) => {
1275 let mut fields = Vec::new();
1276 for field in SField::fields(&doc.graph, to_copy) {
1277 fields.push(field.clone());
1278 }
1279 for field in fields {
1280 if field.is_object() {
1281 match field.value.clone().unbox() {
1282 SVal::Object(nref) => {
1283 let deep_copy = SField::new_object(&mut doc.graph, &field.name, obj);
1284 let to_copy = SVal::Object(nref);
1285 self.operate(pid, doc, "deepCopyFields", &deep_copy, &mut vec![to_copy])?;
1286 },
1287 _ => {}
1288 }
1289 } else {
1290 SData::insert_new(&mut doc.graph, obj, Box::new(field));
1291 }
1292 }
1293 Ok(SVal::Void)
1294 },
1295 _ => {
1296 Err(SError::obj(pid, &doc, "deepCopyFields", "invalid arguments - object to copy not found"))
1297 }
1298 }
1299 },
1300 _ => {
1301 Err(SError::obj(pid, &doc, "deepCopyFields", "invalid arguments - object to copy not found"))
1302 }
1303 }
1304 },
1305 _ => {
1306 Err(SError::obj(pid, &doc, "NotFound", &format!("{} is not a function in the Object Library", name)))
1307 }
1308 }
1309 }
1310
1311 fn exec_val(&self, value: SVal, doc: &mut SDoc, pid: &str, parameters: &mut Vec<SVal>) -> Result<(), SError> {
1313 match value {
1314 SVal::Object(nref) => {
1315 self.operate(pid, doc, "exec", &nref, parameters)?;
1316 },
1317 SVal::FnPtr(dref) => {
1318 SFunc::call(&dref, pid, doc, vec![], false)?;
1319 },
1320 SVal::Array(vals) => {
1321 for val in vals {
1322 self.exec_val(val, doc, pid, parameters)?;
1323 }
1324 },
1325 SVal::Set(vals) => {
1326 for val in vals {
1327 self.exec_val(val, doc, pid, parameters)?;
1328 }
1329 },
1330 SVal::Map(map) => {
1331 for val in map {
1332 self.exec_val(val.1, doc, pid, parameters)?;
1333 }
1334 },
1335 _ => {}
1336 }
1337 Ok(())
1338 }
1339
1340 fn schemafy_field(&self, doc: &mut SDoc, pid: &str, schema: &SNodeRef, target: &SNodeRef, field: &str, value: SVal, remove_invalid: bool, remove_undefined: bool) -> bool {
1342 match value {
1343 SVal::Void |
1344 SVal::Null => {
1345 let mut schema_field_object = None;
1347 let mut target_field_object = None;
1348 if let Some(field) = SField::field(&doc.graph, field, '.', Some(schema)) {
1349 match &field.value {
1350 SVal::Object(nref) => {
1351 schema_field_object = Some(nref.clone());
1352 },
1353 SVal::Boxed(val) => {
1354 let val = val.lock().unwrap();
1355 let val = val.deref();
1356 match val {
1357 SVal::Object(nref) => {
1358 schema_field_object = Some(nref.clone());
1359 },
1360 _ => {}
1361 }
1362 },
1363 _ => {}
1364 }
1365 }
1366 if let Some(field) = SField::field(&doc.graph, field, '.', Some(target)) {
1367 match &field.value {
1368 SVal::Object(nref) => {
1369 target_field_object = Some(nref.clone());
1370 },
1371 SVal::Boxed(val) => {
1372 let val = val.lock().unwrap();
1373 let val = val.deref();
1374 match val {
1375 SVal::Object(nref) => {
1376 target_field_object = Some(nref.clone());
1377 },
1378 _ => {}
1379 }
1380 },
1381 _ => {}
1382 }
1383 }
1384 if let Some(schema_object) = schema_field_object {
1385 if let Some(target_object) = target_field_object {
1386 if let Ok(res) = self.operate(pid, doc, "schemafy", &schema_object, &mut vec![SVal::Object(target_object), SVal::Bool(remove_invalid), SVal::Bool(remove_undefined)]) {
1387 return res.truthy();
1388 }
1389 return false;
1390 }
1391 }
1392 true
1393 },
1394 SVal::Object(another_schema) => {
1395 let mut another_value = None;
1396 if let Some(field) = SField::field(&doc.graph, field, '.', Some(&another_schema)) {
1397 if let Some(schema_val) = field.attributes.get("schema") {
1398 another_value = Some(schema_val.clone());
1399 }
1400 }
1401 if let Some(value) = another_value {
1402 return self.schemafy_field(doc, pid, &another_schema, target, field, value, remove_invalid, remove_undefined);
1403 }
1404 false },
1406 SVal::FnPtr(func_ref) => {
1407 let mut parameters = Vec::new();
1408 let mut valid_check = false; let mut value_index = None;
1410 let mut box_target_field_value = false;
1411 let mut boxed_field_name = None;
1412
1413 if let Some(func) = SData::get::<SFunc>(&doc.graph, &func_ref) {
1414 if func.rtype.is_bool() { valid_check = true; }
1415
1416 let mut added_target = false;
1417 let mut added_schema = false;
1418 let mut added_field = false;
1419 let mut added_value = false;
1420 for param_index in 0..func.params.len() {
1421 let mut done = false;
1422 let param = &func.params[param_index];
1423
1424 if param.ptype.is_object() && param.name != "value" && (!added_target || !added_schema) {
1426 if param.name == "target" || (param.name != "schema" && !added_target) {
1427 added_target = true;
1428 parameters.push(SVal::Object(target.clone()));
1429 } else if param.name == "schema" || !added_schema {
1430 parameters.push(SVal::Object(schema.clone()));
1431 added_schema = true;
1432 }
1433 done = true;
1434 }
1435
1436 if !done && !added_field && param.name != "value" && param.ptype.is_string() {
1438 if param.ptype.is_boxed() {
1439 let val = SVal::String(field.to_string());
1440 let boxed = SVal::Boxed(Arc::new(SMutex::new(val)));
1441 parameters.push(boxed.clone());
1442 boxed_field_name = Some(boxed);
1443 } else {
1444 parameters.push(SVal::String(field.to_string()));
1445 }
1446 added_field = true;
1447 done = true;
1448 }
1449
1450 if !done && !added_value {
1452 value_index = Some(param_index);
1453 added_value = true;
1454
1455 if param.ptype.is_boxed() {
1457 box_target_field_value = true;
1458 }
1459 }
1460 }
1461 }
1462
1463 if let Some(value_index) = value_index {
1465 if let Some(field_ref) = SField::field_ref(&doc.graph, field, '.', Some(target)) {
1466 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, &field_ref) {
1467 if box_target_field_value {
1468 field.value.to_box_ref();
1469 }
1470 parameters.insert(value_index, field.value.clone());
1471 }
1472 } else {
1473 parameters.insert(value_index, SVal::Null);
1475 }
1476 }
1477
1478 if let Ok(res) = SFunc::call(&func_ref, pid, doc, parameters, true) {
1479 if let Some(field_ref) = SField::field_ref(&doc.graph, field, '.', Some(target)) {
1480 if let Some(field) = SData::get_mut::<SField>(&mut doc.graph, &field_ref) {
1481 if let Some(new_name) = boxed_field_name {
1482 field.name = new_name.to_string();
1483 }
1484 if valid_check {
1485 return res.truthy();
1486 } else if !res.is_empty() {
1487 field.value = res;
1488 }
1489 }
1490 } else if valid_check {
1491 return res.truthy();
1492 } else if !res.is_empty() {
1493 let mut field = SField::new(field, res);
1495 if let Some(new_name) = boxed_field_name {
1496 field.name = new_name.to_string();
1497 }
1498 SData::insert_new(&mut doc.graph, target, Box::new(field));
1499 }
1500 return true;
1501 }
1502 false
1503 },
1504 SVal::Tuple(vals) |
1505 SVal::Array(vals) => {
1506 for val in vals {
1507 if !self.schemafy_field(doc, pid, schema, target, field, val, remove_invalid, remove_undefined) {
1508 return false;
1509 }
1510 }
1511 true
1512 },
1513 SVal::Set(set) => {
1514 for val in set {
1515 if !self.schemafy_field(doc, pid, schema, target, field, val, remove_invalid, remove_undefined) {
1516 return false;
1517 }
1518 }
1519 true
1520 },
1521 SVal::Boxed(val) => {
1522 let cloned;
1523 {
1524 let val = val.lock().unwrap();
1525 cloned = val.deref().clone();
1526 }
1527 self.schemafy_field(doc, pid, schema, target, field, cloned, remove_invalid, remove_undefined)
1528 },
1529 _ => false, }
1531 }
1532}
1533impl Library for ObjectLibrary {
1534 fn scope(&self) -> String {
1535 "Object".into()
1536 }
1537 fn call(&self, pid: &str, doc: &mut SDoc, name: &str, parameters: &mut Vec<SVal>) -> Result<SVal, SError> {
1538 if parameters.len() > 0 {
1539 match name {
1540 "toString" => {
1541 return Ok(SVal::String(parameters[0].print(doc)));
1542 },
1543 "or" => {
1544 for param in parameters.drain(..) {
1545 if !param.is_empty() {
1546 return Ok(param);
1547 }
1548 }
1549 return Ok(SVal::Null);
1550 },
1551 _ => {}
1552 }
1553
1554 let mut params;
1555 if parameters.len() > 1 {
1556 params = parameters.drain(1..).collect();
1557 } else {
1558 params = Vec::new();
1559 }
1560 match ¶meters[0] {
1561 SVal::Object(nref) => {
1562 return self.operate(pid, doc, name, nref, &mut params);
1563 },
1564 SVal::Boxed(val) => {
1565 let val = val.lock().unwrap();
1566 let val = val.deref();
1567 match val {
1568 SVal::Object(nref) => {
1569 return self.operate(pid, doc, name, nref, &mut params);
1570 },
1571 _ => {
1572 return Err(SError::obj(pid, &doc, "InvalidArgument", "object argument not found"));
1573 }
1574 }
1575 },
1576 _ => {
1577 return Err(SError::obj(pid, &doc, "InvalidArgument", "object argument not found"));
1578 }
1579 }
1580 } else {
1581 return Err(SError::obj(pid, &doc, "InvalidArgument", "object argument not found"));
1582 }
1583 }
1584}