diff --git a/Cargo.lock b/Cargo.lock index 0414b3d..66a96ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -250,6 +250,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link 0.2.1", ] @@ -1370,17 +1371,6 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" -[[package]] -name = "r2d2" -version = "0.8.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93" -dependencies = [ - "log", - "parking_lot", - "scheduled-thread-pool", -] - [[package]] name = "rand" version = "0.9.2" @@ -1589,15 +1579,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "scheduled-thread-pool" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" -dependencies = [ - "parking_lot", -] - [[package]] name = "scopeguard" version = "1.2.0" @@ -1952,7 +1933,6 @@ dependencies = [ "log4rs", "notify", "postgres", - "r2d2", "regex", "reqwest", "serde", diff --git a/Cargo.toml b/Cargo.toml index 7adeaed..f4c4186 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ log4rs = "1.4.0" serde = { version = "1.0.228", features = ["derive"] } tokio = { version = "1.47", features = ["full"] } tokio-postgres = "0.7" -chrono = "0.4" +chrono = { version= "0.4", features = ["serde"] } dotenv = "0.15.0" reqwest = { version = "0.12", features = ["json", "multipart"] } tower-http = { version = "0.6", features = ["fs"] } @@ -26,7 +26,6 @@ clap = { version = "4.5.51", features = ["derive"] } notify = "8.2.0" arc-swap = "1.7.1" regex = "1.12.2" -r2d2 = "0.8.10" postgres = { version = "0.19", features = ["with-chrono-0_4"] } bb8 = "0.9" bb8-postgres = "0.9" \ No newline at end of file diff --git a/README.md b/README.md index d732530..21509dd 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # tipi-lang -tipi +tipi -Tipi/teepee means: 'the place where they live' in Sioux/Dakota. +Tipi/teepee means: 'the place where they live/dwell' in Sioux/Dakota. see https://sesquiotic.com/2013/02/23/teepee/ Borrowing from that: 'the place where http lives'. diff --git a/src/builtins/globals.rs b/src/builtins/globals.rs index db89e3e..4f1bf32 100644 --- a/src/builtins/globals.rs +++ b/src/builtins/globals.rs @@ -1,14 +1,14 @@ -use crate::builtins::{add, FunctionMap, Signature}; +use crate::DB_POOL; +use crate::builtins::{FunctionMap, Signature, add}; use crate::compiler::ast_pass::Parameter; use crate::compiler::tokens::TokenType; use crate::compiler::tokens::TokenType::{DateTime, ListType, StringType, Void}; use crate::errors::RuntimeError; -use crate::value::{string, Value}; +use crate::value::{Value, string}; use std::cell::RefMut; use std::collections::HashMap; use std::sync::LazyLock; use tokio_postgres::types::Type; -use crate::DB_POOL; pub(crate) static GLOBAL_FUNCTIONS: LazyLock = LazyLock::new(|| { let mut global_functions: FunctionMap = HashMap::new(); @@ -74,7 +74,7 @@ fn sql(_self_val: RefMut, args: Vec) -> Result = HashMap::new(); - for (index, column) in result_row.columns().iter().enumerate() { + for (index, _) in result_row.columns().iter().enumerate() { let column_name = columns.get(index).unwrap().0; let column_type = columns.get(index).unwrap().1; let value = match column_type { @@ -83,9 +83,11 @@ fn sql(_self_val: RefMut, args: Vec) -> Result Value::I64(result_row.get(index)), &Type::FLOAT4 => Value::F32(result_row.get(index)), &Type::FLOAT8 | &Type::NUMERIC => Value::F64(result_row.get(index)), - &Type::CHAR | &Type::VARCHAR | &Type::TEXT | &Type::BPCHAR | &Type::NAME => { - Value::String(result_row.get(index)) - } + &Type::CHAR + | &Type::VARCHAR + | &Type::TEXT + | &Type::BPCHAR + | &Type::NAME => Value::String(result_row.get(index)), &Type::TIMESTAMP | &Type::TIMESTAMPTZ => { Value::DateTime(Box::new(result_row.get(index))) } @@ -100,6 +102,5 @@ fn sql(_self_val: RefMut, args: Vec) -> Result, req: Request, -) -> Result, StatusCode> { +) -> Result, StatusCode> { let method = req.method().to_string().to_ascii_lowercase(); let uri = req.uri(); @@ -131,7 +132,7 @@ async fn handle_any( ) .await { - Ok(value) => Ok(Json(value.to_string())), + Ok(value) => Ok(Json(value)), Err(_) => { // url checks out but function for method not found if state diff --git a/src/value.rs b/src/value.rs index 473131c..2b578d0 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,19 +1,21 @@ use crate::DATE_FORMAT_TIMEZONE; use crate::errors::ValueError; use chrono::{DateTime, Utc}; +use serde::ser::{SerializeMap, SerializeSeq}; +use serde::{Deserialize, Serialize, Serializer}; use std::cmp::Ordering; use std::collections::HashMap; use std::fmt::{Display, Formatter}; use std::hash::{Hash, Hasher}; use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Shl, Shr, Sub}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Object { pub(crate) definition: String, pub(crate) fields: Vec<(String, Value)>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize)] pub enum Value { U32(u32), I32(i32), @@ -34,6 +36,33 @@ pub enum Value { Uuid(String), } +impl Serialize for Value { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Value::String(s) => serializer.serialize_str(s), + Value::I32(n) => serializer.serialize_i32(*n), + Value::I64(n) => serializer.serialize_i64(*n), + Value::U32(n) => serializer.serialize_u32(*n), + Value::U64(n) => serializer.serialize_u64(*n), + Value::F32(f) => serializer.serialize_f32(*f), + Value::F64(f) => serializer.serialize_f64(*f), + Value::Void => serializer.serialize_unit(), + Value::Bool(b) => serializer.serialize_bool(*b), + Value::Char(c) => serializer.serialize_char(*c), + Value::DateTime(d) => serializer.serialize_str(&d.to_string()), + Value::Enum => unimplemented!("TODO implement serialize enums"), + Value::Error(s) => serializer.serialize_str(s), + Value::List(vec) => vec.serialize(serializer), + Value::Map(map) => map.serialize(serializer), + Value::ObjectType(obj) => obj.serialize(serializer), + Value::Uuid(uuid) => serializer.serialize_str(uuid), + } + } +} + pub(crate) fn string(v: impl Into) -> Value { Value::String(v.into()) }