mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 00:45:37 +01:00
add serde, schemars and garde to profiles and options
This commit is contained in:
109
Cargo.lock
generated
109
Cargo.lock
generated
@@ -426,6 +426,15 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.17"
|
||||
@@ -601,6 +610,21 @@ dependencies = [
|
||||
"unicode-width 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "compact_str"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"cfg-if",
|
||||
"itoa",
|
||||
"rustversion",
|
||||
"ryu",
|
||||
"serde",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
@@ -1402,6 +1426,29 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "garde"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a989bd2fd12136080f7825ff410d9239ce84a2a639487fc9d924ee42e2fb84f"
|
||||
dependencies = [
|
||||
"compact_str",
|
||||
"garde_derive",
|
||||
"serde",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "garde_derive"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f7f0545bbbba0a37d4d445890fa5759814e0716f02417b39f6fab292193df68"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "genawaiter"
|
||||
version = "0.99.1"
|
||||
@@ -2132,6 +2179,7 @@ dependencies = [
|
||||
"clap",
|
||||
"dirs 6.0.0",
|
||||
"env_logger 0.10.2",
|
||||
"garde",
|
||||
"hex",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
@@ -2141,6 +2189,7 @@ dependencies = [
|
||||
"regex",
|
||||
"regex-syntax 0.8.5",
|
||||
"rusqlite",
|
||||
"schemars 1.0.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sql_generation",
|
||||
@@ -3109,6 +3158,26 @@ dependencies = [
|
||||
"thiserror 2.0.12",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
|
||||
dependencies = [
|
||||
"ref-cast-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ref-cast-impl"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
@@ -3355,7 +3424,20 @@ checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"indexmap 1.9.3",
|
||||
"schemars_derive",
|
||||
"schemars_derive 0.8.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"ref-cast",
|
||||
"schemars_derive 1.0.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@@ -3372,6 +3454,18 @@ dependencies = [
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d020396d1d138dc19f1165df7545479dcd58d93810dc5d646a16e55abefa80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn 2.0.100",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -3474,6 +3568,9 @@ name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
@@ -3503,10 +3600,12 @@ version = "0.1.4"
|
||||
dependencies = [
|
||||
"anarchist-readable-name-generator-lib 0.2.0",
|
||||
"anyhow",
|
||||
"garde",
|
||||
"hex",
|
||||
"itertools 0.14.0",
|
||||
"rand 0.9.2",
|
||||
"rand_chacha 0.9.0",
|
||||
"schemars 1.0.4",
|
||||
"serde",
|
||||
"tracing",
|
||||
"turso_core",
|
||||
@@ -3528,6 +3627,12 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "str_stack"
|
||||
version = "0.1.0"
|
||||
@@ -4038,7 +4143,7 @@ dependencies = [
|
||||
"mimalloc",
|
||||
"nu-ansi-term 0.50.1",
|
||||
"rustyline",
|
||||
"schemars",
|
||||
"schemars 0.8.22",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
|
||||
@@ -67,6 +67,8 @@ rusqlite = { version = "0.37.0", features = ["bundled"] }
|
||||
itertools = "0.14.0"
|
||||
rand = "0.9.2"
|
||||
tracing = "0.1.41"
|
||||
schemars = "1.0.4"
|
||||
garde = "0.22"
|
||||
|
||||
[profile.release]
|
||||
debug = "line-tables-only"
|
||||
|
||||
@@ -38,3 +38,5 @@ hex = "0.4.3"
|
||||
itertools = "0.14.0"
|
||||
sql_generation = { workspace = true }
|
||||
turso_parser = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
garde = { workspace = true, features = ["derive", "serde"] }
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
#[derive(Debug, Clone)]
|
||||
use garde::Validate;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::{max_dependent, min_dependent};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct IOProfile {
|
||||
#[garde(skip)]
|
||||
pub enable: bool,
|
||||
#[garde(dive)]
|
||||
pub latency: LatencyProfile,
|
||||
// TODO: expand here with header corruption options and faults on specific IO operations
|
||||
}
|
||||
|
||||
impl Default for IOProfile {
|
||||
@@ -13,13 +23,18 @@ impl Default for IOProfile {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct LatencyProfile {
|
||||
#[garde(skip)]
|
||||
pub enable: bool,
|
||||
#[garde(range(min = 0, max = 100))]
|
||||
/// Added IO latency probability
|
||||
pub latency_probability: usize,
|
||||
#[garde(custom(max_dependent(&self.max_tick)))]
|
||||
/// Minimum tick time in microseconds for simulated time
|
||||
pub min_tick: u64,
|
||||
#[garde(custom(min_dependent(&self.min_tick)))]
|
||||
/// Maximum tick time in microseconds for simulated time
|
||||
pub max_tick: u64,
|
||||
}
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
use garde::Validate;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::profiles::{io::IOProfile, query::QueryProfile};
|
||||
|
||||
mod io;
|
||||
mod query;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
pub struct Profile {
|
||||
#[garde(skip)]
|
||||
/// Experimental MVCC feature
|
||||
pub experimental_mvcc: bool,
|
||||
#[garde(dive)]
|
||||
pub io: IOProfile,
|
||||
#[garde(dive)]
|
||||
pub query: QueryProfile,
|
||||
}
|
||||
|
||||
@@ -20,3 +29,27 @@ impl Default for Profile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Minimum value of field is dependent on another field in the struct
|
||||
fn min_dependent<T: PartialOrd + Display>(min: &T) -> impl FnOnce(&T, &()) -> garde::Result + '_ {
|
||||
move |value, _| {
|
||||
if value < min {
|
||||
return Err(garde::Error::new(format!(
|
||||
"`{value}` is smaller than `{min}`"
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Maximum value of field is dependent on another field in the struct
|
||||
fn max_dependent<T: PartialOrd + Display>(max: &T) -> impl FnOnce(&T, &()) -> garde::Result + '_ {
|
||||
move |value, _| {
|
||||
if value > max {
|
||||
return Err(garde::Error::new(format!(
|
||||
"`{value}` is bigger than `{max}`"
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,75 +1,37 @@
|
||||
#[derive(Debug, Default, Clone)]
|
||||
use garde::Validate;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sql_generation::generation::Opts;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct QueryProfile {
|
||||
pub create_table: CreateTableProfile,
|
||||
pub create_index: CreateIndexProfile,
|
||||
pub insert: InsertProfile,
|
||||
pub update: UpdateProfile,
|
||||
pub delete: DeleteProfile,
|
||||
pub drop_table: DropTableProfile,
|
||||
#[garde(dive)]
|
||||
pub gen_opts: Opts,
|
||||
#[garde(skip)]
|
||||
pub create_table: bool,
|
||||
#[garde(skip)]
|
||||
pub create_index: bool,
|
||||
#[garde(skip)]
|
||||
pub insert: bool,
|
||||
#[garde(skip)]
|
||||
pub update: bool,
|
||||
#[garde(skip)]
|
||||
pub delete: bool,
|
||||
#[garde(skip)]
|
||||
pub drop_table: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CreateTableProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for CreateTableProfile {
|
||||
impl Default for QueryProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CreateIndexProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for CreateIndexProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct InsertProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for InsertProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UpdateProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for UpdateProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DeleteProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for DeleteProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DropTableProfile {
|
||||
pub enable: bool,
|
||||
}
|
||||
|
||||
impl Default for DropTableProfile {
|
||||
fn default() -> Self {
|
||||
Self { enable: true }
|
||||
Self {
|
||||
gen_opts: Opts::default(),
|
||||
create_table: true,
|
||||
create_index: true,
|
||||
insert: true,
|
||||
update: true,
|
||||
delete: true,
|
||||
drop_table: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ anarchist-readable-name-generator-lib = "0.2.0"
|
||||
itertools = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
garde = { workspace = true, features = ["derive", "serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.9.0"
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
use std::{
|
||||
fmt::Display,
|
||||
num::{NonZero, NonZeroU32},
|
||||
ops::Range,
|
||||
};
|
||||
|
||||
use garde::Validate;
|
||||
use rand::distr::weighted::WeightedIndex;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::model::table::Table;
|
||||
|
||||
@@ -13,11 +17,15 @@ pub trait GenerationContext {
|
||||
fn opts(&self) -> &Opts;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct Opts {
|
||||
#[garde(skip)]
|
||||
/// Indexes enabled
|
||||
pub indexes: bool,
|
||||
#[garde(dive)]
|
||||
pub table: TableOpts,
|
||||
#[garde(dive)]
|
||||
pub query: QueryOpts,
|
||||
}
|
||||
|
||||
@@ -31,10 +39,13 @@ impl Default for Opts {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct TableOpts {
|
||||
#[garde(dive)]
|
||||
pub large_table: LargeTableOpts,
|
||||
/// Range of numbers of columns to generate
|
||||
#[garde(custom(range_struct_min(1)))]
|
||||
pub column_range: Range<u32>,
|
||||
}
|
||||
|
||||
@@ -49,11 +60,16 @@ impl Default for TableOpts {
|
||||
}
|
||||
|
||||
/// Options for generating large tables
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct LargeTableOpts {
|
||||
#[garde(skip)]
|
||||
pub enable: bool,
|
||||
#[garde(range(min = 0.0, max = 1.0))]
|
||||
pub large_table_prob: f64,
|
||||
|
||||
/// Range of numbers of columns to generate
|
||||
#[garde(custom(range_struct_min(1)))]
|
||||
pub column_range: Range<u32>,
|
||||
}
|
||||
|
||||
@@ -68,16 +84,23 @@ impl Default for LargeTableOpts {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct QueryOpts {
|
||||
#[garde(dive)]
|
||||
pub select: SelectOpts,
|
||||
#[garde(dive)]
|
||||
pub from_clause: FromClauseOpts,
|
||||
#[garde(dive)]
|
||||
pub insert: InsertOpts,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields, default)]
|
||||
pub struct SelectOpts {
|
||||
#[garde(range(min = 0.0, max = 1.0))]
|
||||
pub order_by_prob: f64,
|
||||
#[garde(length(min = 1))]
|
||||
pub compound_selects: Vec<CompoundSelectWeight>,
|
||||
}
|
||||
|
||||
@@ -109,14 +132,17 @@ impl SelectOpts {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct CompoundSelectWeight {
|
||||
pub num_compound_selects: u32,
|
||||
pub weight: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct FromClauseOpts {
|
||||
#[garde(length(min = 1))]
|
||||
pub joins: Vec<JoinWeight>,
|
||||
}
|
||||
|
||||
@@ -147,15 +173,19 @@ impl FromClauseOpts {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct JoinWeight {
|
||||
pub num_joins: u32,
|
||||
pub weight: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, Validate)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct InsertOpts {
|
||||
#[garde(skip)]
|
||||
pub min_rows: NonZeroU32,
|
||||
#[garde(skip)]
|
||||
pub max_rows: NonZeroU32,
|
||||
}
|
||||
|
||||
@@ -167,3 +197,42 @@ impl Default for InsertOpts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn range_struct_min<T: PartialOrd + Display>(
|
||||
min: T,
|
||||
) -> impl FnOnce(&Range<T>, &()) -> garde::Result {
|
||||
move |value, _| {
|
||||
if value.start < min {
|
||||
return Err(garde::Error::new(format!(
|
||||
"range start `{}` is smaller than {min}",
|
||||
value.start
|
||||
)));
|
||||
} else if value.end < min {
|
||||
return Err(garde::Error::new(format!(
|
||||
"range end `{}` is smaller than {min}",
|
||||
value.end
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn range_struct_max<T: PartialOrd + Display>(
|
||||
max: T,
|
||||
) -> impl FnOnce(&Range<T>, &()) -> garde::Result {
|
||||
move |value, _| {
|
||||
if value.start > max {
|
||||
return Err(garde::Error::new(format!(
|
||||
"range start `{}` is smaller than {max}",
|
||||
value.start
|
||||
)));
|
||||
} else if value.end > max {
|
||||
return Err(garde::Error::new(format!(
|
||||
"range end `{}` is smaller than {max}",
|
||||
value.end
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user