#![deny(unused_extern_crates)]
#![deny(warnings)]
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Value {
Null,
Bool(bool),
Int(i64),
F32(f32),
F64(f64),
String(String),
DateTime(DateTime<Utc>),
Blob(Vec<u8>),
}
impl From<i64> for Value {
fn from(i: i64) -> Self {
Self::Int(i)
}
}
impl From<bool> for Value {
fn from(b: bool) -> Self {
Self::Bool(b)
}
}
impl From<f32> for Value {
fn from(f: f32) -> Self {
Self::F32(f)
}
}
impl From<f64> for Value {
fn from(f: f64) -> Self {
Self::F64(f)
}
}
impl From<String> for Value {
fn from(s: String) -> Self {
Self::String(s)
}
}
impl From<&str> for Value {
fn from(s: &str) -> Self {
Self::String(s.into())
}
}
impl From<DateTime<Utc>> for Value {
fn from(dt: DateTime<Utc>) -> Self {
Self::DateTime(dt)
}
}
pub trait FromValueRef {
fn from_value_ref(value: &Value) -> Self;
}
impl FromValueRef for i64 {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => 0,
Value::Bool(b) => {
if *b {
1
} else {
0
}
}
Value::Int(i) => *i,
Value::F32(f) => *f as _,
Value::F64(f) => *f as _,
Value::String(s) => i64::from_str_radix(&s, 10).unwrap_or(0),
Value::DateTime(dt) => dt.timestamp() as _,
Value::Blob(_) => 0,
}
}
}
impl FromValueRef for i32 {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => 0,
Value::Bool(b) => {
if *b {
1
} else {
0
}
}
Value::Int(i) => *i as _,
Value::F32(f) => *f as _,
Value::F64(f) => *f as _,
Value::String(s) => i32::from_str_radix(&s, 10).unwrap_or(0),
Value::DateTime(dt) => dt.timestamp() as _,
Value::Blob(_) => 0,
}
}
}
impl FromValueRef for bool {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => false,
Value::Bool(b) => *b,
Value::Int(i) => *i != 0,
Value::F32(f) => *f != 0.,
Value::F64(f) => *f != 0.,
Value::String(s) => s == "true" || s == "True" || s == "1",
Value::DateTime(dt) => dt.timestamp() != 0,
Value::Blob(b) => b.len() != 0,
}
}
}
impl FromValueRef for f32 {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => 0.,
Value::Bool(b) => {
if *b {
1.
} else {
0.
}
}
Value::Int(i) => *i as _,
Value::F32(f) => *f,
Value::F64(f) => *f as _,
Value::String(s) => s.parse().unwrap_or(0.),
Value::DateTime(dt) => dt.timestamp() as _,
Value::Blob(_) => 0.,
}
}
}
impl FromValueRef for f64 {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => 0.,
Value::Bool(b) => {
if *b {
1.
} else {
0.
}
}
Value::Int(i) => *i as _,
Value::F32(f) => *f as _,
Value::F64(f) => *f,
Value::String(s) => s.parse().unwrap_or(0.),
Value::DateTime(dt) => dt.timestamp() as _,
Value::Blob(_) => 0.,
}
}
}
impl FromValueRef for String {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::Null => Default::default(),
Value::Bool(b) => {
if *b {
"true".into()
} else {
"false".into()
}
}
Value::Int(i) => i.to_string(),
Value::F32(f) => f.to_string(),
Value::F64(f) => f.to_string(),
Value::String(s) => s.clone(),
Value::DateTime(dt) => dt.to_rfc3339(),
Value::Blob(_) => Default::default(),
}
}
}
impl FromValueRef for DateTime<Utc> {
fn from_value_ref(v: &Value) -> Self {
match v {
Value::DateTime(dt) => dt.clone(),
_ => Default::default(),
}
}
}
pub type Col = Value;
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Row {
pub inner: Vec<Col>,
}
impl std::ops::Deref for Row {
type Target = Vec<Col>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl std::ops::DerefMut for Row {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl Row {
pub fn get<T: FromValueRef>(&self, idx: usize) -> T {
T::from_value_ref(&self[idx])
}
}
impl From<Vec<Value>> for Row {
fn from(inner: Vec<Value>) -> Self {
Self { inner }
}
}
pub type Rows = Vec<Row>;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Message {
Execute(String, Vec<Value>),
Fetch(String, Vec<Value>),
FetchOne(String, Vec<Value>),
FetchOptional(String, Vec<Value>),
}
impl Message {
pub fn sql(&self) -> &str {
match self {
Self::Execute(s, _) => s.as_str(),
Self::Fetch(s, _) => s.as_str(),
Self::FetchOne(s, _) => s.as_str(),
Self::FetchOptional(s, _) => s.as_str(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub enum MessageResponse {
Rows(Rows),
Error(String),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RSQliteNodeTlsConfig {
pub key_path: String,
pub cert_path: String,
pub accept_invalid_certificates: bool,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct RSQliteClientTlsConfig {
pub cert_paths: Vec<String>,
pub accept_invalid_certificates: bool,
}
impl RSQliteClientTlsConfig {
pub fn accept_invalid_certificates(mut self, accept_invalid_certificates: bool) -> Self {
self.accept_invalid_certificates = accept_invalid_certificates;
self
}
pub fn add_cert_path(mut self, cert_path: String) -> Self {
self.cert_paths.push(cert_path);
self
}
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct RSQliteNodeConfig {
pub tls_config: Option<RSQliteNodeTlsConfig>,
}
pub use std::sync::atomic::{AtomicBool,Ordering};
pub const IN_TEST: AtomicBool = AtomicBool::new(false);