1use std::cmp::PartialEq;
2use std::collections::HashMap;
3use std::fmt;
4use thiserror::Error;
5
6#[doc(inline)]
7pub use crate::number::Number;
8
9#[derive(Debug, Error)]
10pub enum FuncError {
11 #[error("unable to convert argument from value")]
12 UnableToConvertFromValue,
13 #[error("{0} requires at least {1} argument(s)")]
14 AtLeastXArgs(String, usize),
15 #[error("{0} requires exactly {1} argument(s)")]
16 ExactlyXArgs(String, usize),
17 #[error("{0}")]
18 Generic(String),
19 #[error(transparent)]
20 Other(#[from] anyhow::Error),
21}
22
23pub type Func = fn(&[Value]) -> Result<Value, FuncError>;
25
26#[derive(Clone)]
28pub struct Function {
29 pub f: Func,
30}
31
32impl PartialEq for Function {
33 fn eq(&self, other: &Function) -> bool {
34 self.f as fn(_) -> _ == other.f as fn(_) -> _
35 }
36}
37
38impl fmt::Debug for Function {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "Funtion")
41 }
42}
43
44impl fmt::Display for Function {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 write!(f, "Funtion")
47 }
48}
49
50#[derive(Clone, Debug, PartialEq)]
52pub enum Value {
53 NoValue,
54 Nil,
55 Bool(bool),
56 String(String),
57 Object(HashMap<String, Value>),
58 Map(HashMap<String, Value>),
59 Array(Vec<Value>),
60 Function(Function),
61 Number(Number),
62}
63
64impl Value {
65 pub fn from<T>(t: T) -> Self
66 where
67 T: Into<Value>,
68 {
69 t.into()
70 }
71}
72
73impl fmt::Display for Value {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 match *self {
76 Value::NoValue => write!(f, "<no value>"),
77 Value::Nil => write!(f, "nil"),
78 Value::Bool(ref b) => write!(f, "{}", b),
79 Value::String(ref s) => write!(f, "{}", s),
80 Value::Function(ref func) => write!(f, "{}", func),
81 Value::Number(ref n) => write!(f, "{}", n),
82 Value::Array(ref a) => write!(f, "{:?}", a),
83 Value::Object(ref o) => write!(f, "{:?}", o),
84 Value::Map(ref m) => write!(f, "{:?}", m),
85 }
86 }
87}