#![deny(unused_extern_crates)]
#![deny(warnings)]
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
pub use either::Either;
#[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(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Col {
pub value: Value,
pub ordinal: u64,
}
impl Col {
pub fn new(value: Value, ordinal: u64) -> Self {
Self {
value,
ordinal,
}
}
}
impl From<(Value,u64)> for Col {
fn from((value,ordinal): (Value,u64))->Self {
Self {
value,
ordinal,
}
}
}
impl std::ops::Deref for Col {
type Target = Value;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl std::ops::DerefMut for Col {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.value
}
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Row {
pub columns: Vec<Column>,
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<Column>,Vec<Col>)> for Row {
fn from((columns,inner): (Vec<Column>,Vec<Col>)) -> Self {
Self { columns, inner }
}
}
pub type Rows = Vec<Row>;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum TypeInfo {
Null,
Int,
Float,
Text,
Blob,
Numeric,
Bool,
Int64,
Date,
Time,
DateTime,
}
impl TypeInfo {
pub fn is_null(&self) -> bool {
match self {
TypeInfo::Null=>true,
_=>false,
}
}
pub fn name(&self) -> &'static str {
match self {
Self::Null => "NULL",
Self::Int => "INT",
Self::Float => "FLOAT",
Self::Text => "FLOAT",
Self::Blob => "BLOB",
Self::Numeric => "NUMERIC",
Self::Bool => "BOOL",
Self::Int64 => "INTEGER",
Self::Date => "DATE",
Self::Time => "TIME",
Self::DateTime => "DATETIME",
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Column {
pub ordinal: usize,
pub name: String,
pub type_info: TypeInfo,
}
#[derive(Serialize, Deserialize, Debug, Default)]
pub struct QueryResult {
pub last_insert_rowid: i64,
pub changes: u64,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum Message {
Execute(String, Vec<Value>),
Fetch(String, Vec<Value>),
FetchOne(String, Vec<Value>),
FetchOptional(String, Vec<Value>),
FetchMany(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(),
Self::FetchMany(s, _) => s.as_str(),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub enum MessageResponse {
Rows(Rows),
QueryResult(QueryResult),
QueryResultsAndRows(Vec<Result<Either<QueryResult,Row>,String>>),
Error(String),
}
#[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
}
}