1use crate::value::Value;
4use std::collections::HashMap;
5use std::cell::RefCell;
6use std::collections::HashSet;
7use std::rc::Rc;
8use uuid::Uuid;
9
10use crate::chunk::Chunk;
11
12#[derive(Debug, Clone)]
13pub struct FsFunction {
14 pub arity: usize,
15 pub chunk: Chunk,
16 pub name: String,
17 pub slot_names: Vec<String>,
20}
21
22impl PartialEq for FsFunction {
23 fn eq(&self, _other: &Self) -> bool {
24 false
25 }
26}
27
28#[derive(Debug, Clone)]
29pub enum Obj {
30 String(String),
31 List(Vec<Value>),
32 Range(RangeObject),
33 Bytes(Vec<u8>),
34 Guid(Uuid),
35 DateTimeTicks(i64),
36
37 Kvc(Rc<RefCell<KvcObject>>),
38
39 Provider(Rc<ProviderObject>),
40 Function(std::rc::Rc<FsFunction>),
41
42 NativeFn(fn(&[Value]) -> Value),
43}
44
45#[derive(Debug, Clone, PartialEq)]
46pub struct RangeObject {
47 pub start: i64,
48 pub count: usize,
49}
50
51#[derive(Debug)]
52pub struct ProviderObject {
53 pub current: Value,
54 pub parent: Option<Value>,
55}
56
57#[derive(Debug)]
58pub struct KvcObject {
59 pub entries: HashMap<String, Rc<FsFunction>>,
60 pub cache: HashMap<String, Value>,
61 pub evaluating: HashSet<String>,
62 pub parent: Option<Value>,
63 pub order: Vec<String>,
64 pub display_names: HashMap<String, String>,
65}
66
67impl PartialEq for Obj {
68 fn eq(&self, other: &Self) -> bool {
69 match (self, other) {
70 (Obj::String(a), Obj::String(b)) => a == b,
71 (Obj::List(a), Obj::List(b)) => a == b,
72 (Obj::Range(a), Obj::Range(b)) => a == b,
73 (Obj::Bytes(a), Obj::Bytes(b)) => a == b,
74 (Obj::Guid(a), Obj::Guid(b)) => a == b,
75 (Obj::DateTimeTicks(a), Obj::DateTimeTicks(b)) => a == b,
76 (Obj::Kvc(_), Obj::Kvc(_)) => false,
77 (Obj::Provider(_), Obj::Provider(_)) => false,
78 (Obj::NativeFn(a), Obj::NativeFn(b)) => {
79 std::ptr::eq(*a as *const (), *b as *const ())
80 }
81 _ => false,
82 }
83 }
84}
85
86impl std::fmt::Display for Obj {
87 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
88 match self {
89 Obj::String(s) => write!(f, "{}", s),
90 Obj::List(l) => {
91 let s: Vec<String> = l.iter().map(|v| v.to_string()).collect();
92 write!(f, "[{}]", s.join(", "))
93 },
94 Obj::Range(r) => write!(f, "<range start={} count={}>", r.start, r.count),
95 Obj::Bytes(b) => write!(f, "<bytes len={}>", b.len()),
96 Obj::Guid(g) => write!(f, "{}", g),
97 Obj::DateTimeTicks(ticks) => write!(f, "<datetime ticks={}>", ticks),
98 Obj::Kvc(kvc) => {
99 let kvc = kvc.borrow();
100 write!(f, "{{ ")?;
101 let mut first = true;
102 for k in kvc.order.iter() {
103 if !first { write!(f, ", ")?; }
104 first = false;
105 let display = kvc.display_names.get(k).map(|s| s.as_str()).unwrap_or(k.as_str());
106 if let Some(v) = kvc.cache.get(k) {
107 write!(f, "{}: {}", display, v)?;
108 } else {
109 write!(f, "{}: <lazy>", display)?;
110 }
111 }
112 write!(f, " }}")
113 }
114 Obj::Provider(_) => write!(f, "<provider>"),
115 Obj::Function(func) => write!(f, "<fn {}>", func.name),
116 Obj::NativeFn(_) => write!(f, "<native fn>"),
117 }
118 }
119}