1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::fmt::Result;
4use std::fmt::{Display, Formatter};
5use std::fs::File;
6use std::path::PathBuf;
7
8#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
9pub enum Argument {
10 None,
11 Int(i32),
12 Long(i64),
13 Float(f32),
14 Double(f64),
15 Bool(bool),
16 String(String),
17 File(RigzFile),
18 Object(HashMap<String, Argument>),
19 List(Vec<Argument>),
20 FunctionCall(FunctionCall),
21 Definition(Definition),
22 Error(String),
23}
24
25#[derive(Debug, Deserialize, Serialize)]
26pub struct RigzFile {
27 pub file: PathBuf,
28 #[serde(skip_serializing, skip_deserializing)]
29 internal: Option<File>,
30}
31
32impl RigzFile {
33 pub fn file(self) -> Option<File> {
34 self.internal
35 }
36}
37
38impl Display for RigzFile {
39 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
40 write!(f, "{}", self.file.to_str().unwrap_or("<invalid-utf>"))
41 }
42}
43
44impl Clone for RigzFile {
45 fn clone(&self) -> Self {
46 let file = self.file.clone();
47 if file.exists() {
48 RigzFile {
49 internal: Some(File::open(&file).expect("Failed to open file")),
50 file,
51 }
52 } else {
53 RigzFile {
54 file,
55 internal: None,
56 }
57 }
58 }
59}
60
61impl PartialEq for RigzFile {
62 fn eq(&self, other: &Self) -> bool {
63 self.file == other.file
64 }
65}
66
67#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
68#[repr(C)]
69pub enum Definition {
70 None,
71 One(HashMap<String, Argument>),
72 Many(Vec<Argument>),
73}
74
75impl Display for Argument {
76 fn fmt(&self, f: &mut Formatter<'_>) -> Result {
77 match self {
78 Argument::None => write!(f, "none"),
79 Argument::Int(i) => write!(f, "{}", i),
80 Argument::Long(l) => write!(f, "{}", l),
81 Argument::Float(fl) => write!(f, "{}", fl),
82 Argument::Double(d) => write!(f, "{}", d),
83 Argument::Bool(b) => write!(f, "{}", b),
84 Argument::String(s) => write!(f, "{}", s),
85 Argument::Object(o) => write!(f, "{:?}", o),
86 Argument::List(l) => write!(f, "{:?}", l),
87 Argument::FunctionCall(fc) => write!(f, "{:?}", fc),
88 Argument::Definition(d) => write!(f, "{:?}", d),
89 Argument::Error(e) => write!(f, "Error: {}", e),
90 Argument::File(file) => write!(f, "{}", file),
91 }
92 }
93}
94
95#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
96pub struct FunctionCall {
97 pub name: String,
98 pub args: Vec<Argument>,
99 pub definition: Definition,
100}
101
102#[derive(Debug, PartialEq)]
103pub enum RuntimeStatus<T> {
104 Ok(T),
105 NotFound,
106 Err(String),
107}
108
109pub trait Module {
110 fn name(&self) -> &str;
111
112 fn root(&self) -> PathBuf;
113
114 fn function_call(
115 &self,
116 name: &str,
117 arguments: Vec<Argument>,
118 definition: Definition,
119 prior_result: Argument,
120 ) -> RuntimeStatus<Argument>;
121
122 fn initialize(&self, args: InitializationArgs) -> RuntimeStatus<()> {
123 if args.all_errors_fatal {
124 RuntimeStatus::Err("Initialization Function Not Found".into())
125 } else {
126 RuntimeStatus::NotFound
127 }
128 }
129}
130
131
132#[derive(Clone, Copy)]
133pub struct InitializationArgs {
134 pub all_errors_fatal: bool,
135 pub ignore_symbol_not_found: bool,
136 pub prefer_none_over_prior_result: bool,
137 pub require_aliases: bool,
138}