1use std::fmt::{self, Display};
2
3use anyhow::Result;
4use common::fail;
5use surrealdb_types::{SqlFormat, ToSql};
6
7use crate::expr::Kind;
8use crate::sql;
9use crate::val::File;
10
11#[derive(Clone, Debug, Eq, PartialEq, Hash)]
12pub enum ModuleExecutable {
13 Surrealism(SurrealismExecutable),
14 Silo(SiloExecutable),
15}
16
17impl ToSql for ModuleExecutable {
18 fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
19 let module_executable: crate::sql::ModuleExecutable = self.clone().into();
20 module_executable.fmt_sql(f, sql_fmt);
21 }
22}
23
24#[derive(Clone, Debug, Eq, PartialEq, Hash)]
25pub struct Signature {
26 pub args: Vec<Kind>,
27 pub returns: Option<Kind>,
28 pub writeable: bool,
29}
30
31#[derive(Clone, Debug, Eq, PartialEq, Hash)]
32pub struct SurrealismExecutable(pub File);
33
34impl ToSql for SurrealismExecutable {
35 fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
36 let surrealism_executable: crate::sql::SurrealismExecutable = self.clone().into();
37 surrealism_executable.fmt_sql(f, sql_fmt);
38 }
39}
40
41#[derive(Clone, Debug, Eq, PartialEq, Hash)]
42pub struct SiloExecutable {
43 pub organisation: String,
44 pub package: String,
45 pub major: u32,
46 pub minor: u32,
47 pub patch: u32,
48}
49
50impl ToSql for SiloExecutable {
51 fn fmt_sql(&self, f: &mut String, sql_fmt: SqlFormat) {
52 let silo_executable: crate::sql::SiloExecutable = self.clone().into();
53 silo_executable.fmt_sql(f, sql_fmt);
54 }
55}
56
57#[derive(Clone, Debug, Eq, PartialEq, Hash)]
62pub enum ModuleName {
63 Module(String),
64 Silo(String, String, u32, u32, u32),
65}
66
67impl ModuleName {
68 pub fn get_storage_name(&self) -> String {
69 match self {
70 ModuleName::Module(name) => format!("mod::{}", name),
71 ModuleName::Silo(org, pkg, major, minor, patch) => {
72 format!("silo::{org}::{pkg}::<{major}.{minor}.{patch}>")
73 }
74 }
75 }
76}
77
78impl From<sql::module::ModuleName> for ModuleName {
79 fn from(v: sql::module::ModuleName) -> Self {
80 match v {
81 sql::module::ModuleName::Module(name) => ModuleName::Module(name),
82 sql::module::ModuleName::Silo(org, pkg, major, minor, patch) => {
83 ModuleName::Silo(org, pkg, major, minor, patch)
84 }
85 }
86 }
87}
88
89impl From<ModuleName> for sql::module::ModuleName {
90 fn from(v: ModuleName) -> Self {
91 match v {
92 ModuleName::Module(name) => sql::module::ModuleName::Module(name),
93 ModuleName::Silo(org, pkg, major, minor, patch) => {
94 sql::module::ModuleName::Silo(org, pkg, major, minor, patch)
95 }
96 }
97 }
98}
99
100impl<'a> TryFrom<&'a crate::expr::statements::DefineModuleStatement> for ModuleName {
101 type Error = anyhow::Error;
102 fn try_from(
103 value: &'a crate::expr::statements::DefineModuleStatement,
104 ) -> Result<Self, Self::Error> {
105 if let Some(name) = &value.name {
106 Ok(ModuleName::Module(name.clone()))
107 } else if let crate::expr::ModuleExecutable::Silo(silo) = &value.executable {
108 Ok(ModuleName::Silo(
109 silo.organisation.clone(),
110 silo.package.clone(),
111 silo.major,
112 silo.minor,
113 silo.patch,
114 ))
115 } else {
116 fail!("A module without a name cannot be stored")
119 }
120 }
121}
122
123impl Display for ModuleName {
124 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
125 match self {
126 ModuleName::Module(name) => write!(f, "mod::{}", name),
127 ModuleName::Silo(org, pkg, major, minor, patch) => {
128 write!(f, "silo::{org}::{pkg}::<{major}.{minor}.{patch}>")
129 }
130 }
131 }
132}