style: format the whole tree with cargo fmt (stock defaults, #35)
One-time, mechanical reformat — no functional changes. The tree was not rustfmt-clean (~1800 hunks across ~100 files); this brings it to stock `cargo fmt` defaults so a `cargo fmt --check` CI gate can follow. Behaviour-preserving: 2509 pass / 0 fail / 1 ignored (unchanged baseline), clippy clean. A .git-blame-ignore-revs entry follows so `git blame` skips this commit.
This commit is contained in:
+29
-13
@@ -150,7 +150,9 @@ fn encode_cell(ty: Type, value: &CellValue) -> Result<Cell, String> {
|
||||
other => Err(format!("expected date/datetime (text), got {other:?}")),
|
||||
},
|
||||
Type::Blob => match value {
|
||||
CellValue::Blob(bytes) => Ok(Cell::Plain(base64::engine::general_purpose::STANDARD.encode(bytes))),
|
||||
CellValue::Blob(bytes) => Ok(Cell::Plain(
|
||||
base64::engine::general_purpose::STANDARD.encode(bytes),
|
||||
)),
|
||||
other => Err(format!("expected blob, got {other:?}")),
|
||||
},
|
||||
Type::Serial => match value {
|
||||
@@ -169,7 +171,11 @@ fn format_real(f: f64) -> String {
|
||||
if f.is_nan() {
|
||||
"nan".to_string()
|
||||
} else if f.is_infinite() {
|
||||
if f > 0.0 { "inf".to_string() } else { "-inf".to_string() }
|
||||
if f > 0.0 {
|
||||
"inf".to_string()
|
||||
} else {
|
||||
"-inf".to_string()
|
||||
}
|
||||
} else {
|
||||
// Default `{}` formatting on f64 emits a shortest
|
||||
// round-tripping decimal — exactly what the ADR asks
|
||||
@@ -318,8 +324,7 @@ fn parse_field(bytes: &[u8]) -> Result<(RawCell, usize), CsvError> {
|
||||
_ => i += 1,
|
||||
}
|
||||
}
|
||||
let content =
|
||||
String::from_utf8(bytes[..i].to_vec()).map_err(|_| CsvError::InvalidUtf8)?;
|
||||
let content = String::from_utf8(bytes[..i].to_vec()).map_err(|_| CsvError::InvalidUtf8)?;
|
||||
Ok((
|
||||
RawCell {
|
||||
content,
|
||||
@@ -435,7 +440,10 @@ mod tests {
|
||||
name: "T".to_string(),
|
||||
columns: vec![col("n", Type::Int), col("r", Type::Real)],
|
||||
rows: vec![
|
||||
vec![CellValue::Integer(42), CellValue::Real(std::f64::consts::PI)],
|
||||
vec![
|
||||
CellValue::Integer(42),
|
||||
CellValue::Real(std::f64::consts::PI),
|
||||
],
|
||||
vec![CellValue::Integer(-7), CellValue::Real(0.0)],
|
||||
],
|
||||
})
|
||||
@@ -452,10 +460,7 @@ mod tests {
|
||||
let body = serialize_table(&TableSnapshot {
|
||||
name: "T".to_string(),
|
||||
columns: vec![col("b", Type::Bool)],
|
||||
rows: vec![
|
||||
vec![CellValue::Integer(1)],
|
||||
vec![CellValue::Integer(0)],
|
||||
],
|
||||
rows: vec![vec![CellValue::Integer(1)], vec![CellValue::Integer(0)]],
|
||||
})
|
||||
.unwrap();
|
||||
let s = String::from_utf8(body).unwrap();
|
||||
@@ -555,13 +560,21 @@ mod tests {
|
||||
let body = serialize_table(&table).unwrap();
|
||||
let parsed = parse_csv(std::str::from_utf8(&body).unwrap()).unwrap();
|
||||
let row = &parsed.rows[0];
|
||||
assert!(matches!(decode_cell(Type::Int, &row[0]).unwrap(), CellValue::Integer(42)));
|
||||
assert!(matches!(
|
||||
decode_cell(Type::Int, &row[0]).unwrap(),
|
||||
CellValue::Integer(42)
|
||||
));
|
||||
match decode_cell(Type::Real, &row[1]).unwrap() {
|
||||
CellValue::Real(f) => assert!((f - std::f64::consts::PI).abs() < 1e-12),
|
||||
other => panic!("got {other:?}"),
|
||||
}
|
||||
assert!(matches!(decode_cell(Type::Bool, &row[2]).unwrap(), CellValue::Integer(1)));
|
||||
assert!(matches!(decode_cell(Type::Blob, &row[3]).unwrap(), CellValue::Blob(b) if b == b"hi"));
|
||||
assert!(matches!(
|
||||
decode_cell(Type::Bool, &row[2]).unwrap(),
|
||||
CellValue::Integer(1)
|
||||
));
|
||||
assert!(
|
||||
matches!(decode_cell(Type::Blob, &row[3]).unwrap(), CellValue::Blob(b) if b == b"hi")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -572,7 +585,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn decode_cell_reports_friendly_error_for_bad_int() {
|
||||
let cell = RawCell { content: "abc".to_string(), was_quoted: false };
|
||||
let cell = RawCell {
|
||||
content: "abc".to_string(),
|
||||
was_quoted: false,
|
||||
};
|
||||
let err = decode_cell(Type::Int, &cell).expect_err("must error");
|
||||
assert!(err.contains("integer"));
|
||||
assert!(err.contains("abc"));
|
||||
|
||||
+33
-18
@@ -108,10 +108,7 @@ pub(super) fn read_recent_sources(
|
||||
});
|
||||
}
|
||||
};
|
||||
let mut sources: Vec<String> = body
|
||||
.lines()
|
||||
.filter_map(parse_record_source)
|
||||
.collect();
|
||||
let mut sources: Vec<String> = body.lines().filter_map(parse_record_source).collect();
|
||||
if sources.len() > max_n {
|
||||
let skip = sources.len() - max_n;
|
||||
sources.drain(0..skip);
|
||||
@@ -187,12 +184,26 @@ fn looks_like_iso8601(s: &str) -> bool {
|
||||
return false;
|
||||
}
|
||||
let digit = |i: usize| b[i].is_ascii_digit();
|
||||
digit(0) && digit(1) && digit(2) && digit(3) && b[4] == b'-'
|
||||
&& digit(5) && digit(6) && b[7] == b'-'
|
||||
&& digit(8) && digit(9) && b[10] == b'T'
|
||||
&& digit(11) && digit(12) && b[13] == b':'
|
||||
&& digit(14) && digit(15) && b[16] == b':'
|
||||
&& digit(17) && digit(18) && b[19] == b'Z'
|
||||
digit(0)
|
||||
&& digit(1)
|
||||
&& digit(2)
|
||||
&& digit(3)
|
||||
&& b[4] == b'-'
|
||||
&& digit(5)
|
||||
&& digit(6)
|
||||
&& b[7] == b'-'
|
||||
&& digit(8)
|
||||
&& digit(9)
|
||||
&& b[10] == b'T'
|
||||
&& digit(11)
|
||||
&& digit(12)
|
||||
&& b[13] == b':'
|
||||
&& digit(14)
|
||||
&& digit(15)
|
||||
&& b[16] == b':'
|
||||
&& digit(17)
|
||||
&& digit(18)
|
||||
&& b[19] == b'Z'
|
||||
}
|
||||
|
||||
fn unescape_command(s: &str) -> String {
|
||||
@@ -321,10 +332,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn parse_journal_record_ok_extracts_unescaped_source() {
|
||||
let rec = parse_journal_record(
|
||||
"2026-05-24T10:00:00Z|ok|create table T with pk id(int)",
|
||||
)
|
||||
.expect("valid ok journal record");
|
||||
let rec = parse_journal_record("2026-05-24T10:00:00Z|ok|create table T with pk id(int)")
|
||||
.expect("valid ok journal record");
|
||||
assert!(rec.status_is_ok);
|
||||
assert_eq!(rec.source, "create table T with pk id(int)");
|
||||
}
|
||||
@@ -370,8 +379,8 @@ mod tests {
|
||||
fn parse_journal_record_preserves_pipe_in_source() {
|
||||
// `|` is not escaped by the writer (it's a valid SQL char);
|
||||
// `splitn(3, '|')` keeps everything after the second `|`.
|
||||
let rec = parse_journal_record("2026-05-24T10:00:00Z|ok|select 'a|b' from t")
|
||||
.expect("ok record");
|
||||
let rec =
|
||||
parse_journal_record("2026-05-24T10:00:00Z|ok|select 'a|b' from t").expect("ok record");
|
||||
assert_eq!(rec.source, "select 'a|b' from t");
|
||||
}
|
||||
|
||||
@@ -406,7 +415,10 @@ mod tests {
|
||||
#[test]
|
||||
fn iso8601_known_seconds() {
|
||||
assert_eq!(iso8601_from_unix_secs(0), "1970-01-01T00:00:00Z");
|
||||
assert_eq!(iso8601_from_unix_secs(1_778_112_000), "2026-05-07T00:00:00Z");
|
||||
assert_eq!(
|
||||
iso8601_from_unix_secs(1_778_112_000),
|
||||
"2026-05-07T00:00:00Z"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -437,7 +449,10 @@ mod tests {
|
||||
.collect();
|
||||
std::fs::write(&path, body).unwrap();
|
||||
let got = read_recent_sources(&path, 3).unwrap();
|
||||
assert_eq!(got, vec!["cmd7".to_string(), "cmd8".to_string(), "cmd9".to_string()]);
|
||||
assert_eq!(
|
||||
got,
|
||||
vec!["cmd7".to_string(), "cmd8".to_string(), "cmd9".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -82,7 +82,10 @@ impl Default for MigratorRegistry {
|
||||
#[derive(Debug)]
|
||||
pub enum MigrateError {
|
||||
VersionParse(String),
|
||||
NewerThanSupported { file: u32, latest: u32 },
|
||||
NewerThanSupported {
|
||||
file: u32,
|
||||
latest: u32,
|
||||
},
|
||||
NoMigratorForVersion(u32),
|
||||
StepFailed {
|
||||
from: u32,
|
||||
@@ -108,10 +111,9 @@ impl std::fmt::Display for MigrateError {
|
||||
file = file,
|
||||
latest = latest,
|
||||
)),
|
||||
Self::NoMigratorForVersion(v) => f.write_str(&crate::t!(
|
||||
"persistence.migrate.no_migrator",
|
||||
version = v,
|
||||
)),
|
||||
Self::NoMigratorForVersion(v) => {
|
||||
f.write_str(&crate::t!("persistence.migrate.no_migrator", version = v,))
|
||||
}
|
||||
Self::StepFailed { from, to, source } => f.write_str(&crate::t!(
|
||||
"persistence.migrate.step_failed",
|
||||
from = from,
|
||||
@@ -192,8 +194,11 @@ pub fn migrate_to_latest(
|
||||
|
||||
// Write the .bak before any transformation runs so a
|
||||
// mid-migration crash leaves the original recoverable.
|
||||
let bak_path =
|
||||
project_path.join(format!("{}.v{}.bak", crate::project::PROJECT_YAML, file_version));
|
||||
let bak_path = project_path.join(format!(
|
||||
"{}.v{}.bak",
|
||||
crate::project::PROJECT_YAML,
|
||||
file_version
|
||||
));
|
||||
std::fs::write(&bak_path, body).map_err(|source| MigrateError::Io {
|
||||
path: bak_path.clone(),
|
||||
source,
|
||||
@@ -214,8 +219,8 @@ pub fn migrate_to_latest(
|
||||
// Sanity: the new body must declare the next version.
|
||||
// If a migrator forgets to bump, we'd loop endlessly
|
||||
// through the chain — catch it here.
|
||||
let advertised = read_version(&next_body)
|
||||
.map_err(|e| MigrateError::BadOutput(e.to_string()))?;
|
||||
let advertised =
|
||||
read_version(&next_body).map_err(|e| MigrateError::BadOutput(e.to_string()))?;
|
||||
if advertised != v + 1 {
|
||||
return Err(MigrateError::BadOutput(format!(
|
||||
"v{v}→v{} migrator left version field at {advertised}",
|
||||
@@ -281,9 +286,8 @@ fn read_version(body: &str) -> Result<u32, MigrateError> {
|
||||
struct VersionOnly {
|
||||
version: u32,
|
||||
}
|
||||
let v: VersionOnly = serde_norway::from_str(body).map_err(|e| {
|
||||
MigrateError::VersionParse(e.to_string())
|
||||
})?;
|
||||
let v: VersionOnly =
|
||||
serde_norway::from_str(body).map_err(|e| MigrateError::VersionParse(e.to_string()))?;
|
||||
Ok(v.version)
|
||||
}
|
||||
|
||||
@@ -309,12 +313,8 @@ mod tests {
|
||||
#[test]
|
||||
fn no_migration_runs_when_body_already_latest() {
|
||||
let tmp = tempdir();
|
||||
let outcome = migrate_to_latest(
|
||||
&v1_body(),
|
||||
&MigratorRegistry::production(),
|
||||
tmp.path(),
|
||||
)
|
||||
.unwrap();
|
||||
let outcome =
|
||||
migrate_to_latest(&v1_body(), &MigratorRegistry::production(), tmp.path()).unwrap();
|
||||
assert_eq!(outcome.body, v1_body());
|
||||
assert_eq!(outcome.migrated_from, None);
|
||||
// No .bak written when nothing migrated.
|
||||
@@ -328,7 +328,13 @@ mod tests {
|
||||
let err = migrate_to_latest(body, &MigratorRegistry::production(), Path::new("/tmp"))
|
||||
.expect_err("must reject");
|
||||
assert!(
|
||||
matches!(err, MigrateError::NewerThanSupported { file: 99, latest: 1 }),
|
||||
matches!(
|
||||
err,
|
||||
MigrateError::NewerThanSupported {
|
||||
file: 99,
|
||||
latest: 1
|
||||
}
|
||||
),
|
||||
"got: {err:?}",
|
||||
);
|
||||
}
|
||||
@@ -366,12 +372,7 @@ mod tests {
|
||||
#[test]
|
||||
fn migrate_runs_chain_and_writes_bak() {
|
||||
let tmp = tempdir();
|
||||
let outcome = migrate_to_latest(
|
||||
&v1_body(),
|
||||
®istry_with_v1_to_v2(),
|
||||
tmp.path(),
|
||||
)
|
||||
.unwrap();
|
||||
let outcome = migrate_to_latest(&v1_body(), ®istry_with_v1_to_v2(), tmp.path()).unwrap();
|
||||
assert_eq!(outcome.migrated_from, Some(1));
|
||||
assert!(outcome.body.contains("version: 2"));
|
||||
let bak = tmp.path().join("project.yaml.v1.bak");
|
||||
@@ -396,11 +397,8 @@ mod tests {
|
||||
let tmp = tempdir();
|
||||
let yaml_path = tmp.path().join("project.yaml");
|
||||
std::fs::write(&yaml_path, v1_body()).unwrap();
|
||||
let outcome = ensure_project_yaml_migrated(
|
||||
tmp.path(),
|
||||
&MigratorRegistry::production(),
|
||||
)
|
||||
.unwrap();
|
||||
let outcome =
|
||||
ensure_project_yaml_migrated(tmp.path(), &MigratorRegistry::production()).unwrap();
|
||||
assert_eq!(outcome.migrated_from, None);
|
||||
// File unchanged.
|
||||
let on_disk = std::fs::read_to_string(&yaml_path).unwrap();
|
||||
@@ -413,36 +411,32 @@ mod tests {
|
||||
let tmp = tempdir();
|
||||
let yaml_path = tmp.path().join("project.yaml");
|
||||
std::fs::write(&yaml_path, v1_body()).unwrap();
|
||||
let outcome = ensure_project_yaml_migrated(
|
||||
tmp.path(),
|
||||
®istry_with_v1_to_v2(),
|
||||
)
|
||||
.unwrap();
|
||||
let outcome = ensure_project_yaml_migrated(tmp.path(), ®istry_with_v1_to_v2()).unwrap();
|
||||
assert_eq!(outcome.migrated_from, Some(1));
|
||||
let on_disk = std::fs::read_to_string(&yaml_path).unwrap();
|
||||
assert!(on_disk.contains("version: 2"), "got: {on_disk}");
|
||||
let bak = tmp.path().join("project.yaml.v1.bak");
|
||||
assert!(bak.exists());
|
||||
assert!(std::fs::read_to_string(&bak).unwrap().contains("version: 1"));
|
||||
assert!(
|
||||
std::fs::read_to_string(&bak)
|
||||
.unwrap()
|
||||
.contains("version: 1")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ensure_yaml_migrated_handles_missing_yaml() {
|
||||
let tmp = tempdir();
|
||||
// No project.yaml exists.
|
||||
let outcome = ensure_project_yaml_migrated(
|
||||
tmp.path(),
|
||||
&MigratorRegistry::production(),
|
||||
)
|
||||
.unwrap();
|
||||
let outcome =
|
||||
ensure_project_yaml_migrated(tmp.path(), &MigratorRegistry::production()).unwrap();
|
||||
assert_eq!(outcome.migrated_from, None);
|
||||
assert!(outcome.body.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migrator_that_returns_internal_error_propagates() {
|
||||
let bad: MigrateFn =
|
||||
|_| Err(MigrateError::VersionParse("simulated".to_string()));
|
||||
let bad: MigrateFn = |_| Err(MigrateError::VersionParse("simulated".to_string()));
|
||||
let registry = MigratorRegistry {
|
||||
migrators: vec![bad],
|
||||
};
|
||||
|
||||
+19
-19
@@ -368,12 +368,11 @@ impl Persistence {
|
||||
path: data_dir.clone(),
|
||||
source,
|
||||
})?;
|
||||
let body =
|
||||
csv_io::serialize_table(table).map_err(|message| PersistenceError::Encode {
|
||||
kind: "CSV",
|
||||
path: data_dir.join(format!("{}.csv", table.name)),
|
||||
message,
|
||||
})?;
|
||||
let body = csv_io::serialize_table(table).map_err(|message| PersistenceError::Encode {
|
||||
kind: "CSV",
|
||||
path: data_dir.join(format!("{}.csv", table.name)),
|
||||
message,
|
||||
})?;
|
||||
atomic_write(&data_dir.join(format!("{}.csv", table.name)), &body)
|
||||
}
|
||||
|
||||
@@ -406,11 +405,8 @@ impl Persistence {
|
||||
) -> Result<(), PersistenceError> {
|
||||
let path = self.project_path.join(HISTORY_LOG);
|
||||
let status = history::status_token(history::STATUS_OK, advanced);
|
||||
let line = history::format_record_with_status(
|
||||
command_text,
|
||||
history::utc_iso8601_now(),
|
||||
&status,
|
||||
);
|
||||
let line =
|
||||
history::format_record_with_status(command_text, history::utc_iso8601_now(), &status);
|
||||
debug!(
|
||||
len = command_text.len(),
|
||||
advanced, "persist: append ok record to history.log"
|
||||
@@ -432,11 +428,8 @@ impl Persistence {
|
||||
) -> Result<(), PersistenceError> {
|
||||
let path = self.project_path.join(HISTORY_LOG);
|
||||
let status = history::status_token(history::STATUS_ERR, advanced);
|
||||
let line = history::format_record_with_status(
|
||||
command_text,
|
||||
history::utc_iso8601_now(),
|
||||
&status,
|
||||
);
|
||||
let line =
|
||||
history::format_record_with_status(command_text, history::utc_iso8601_now(), &status);
|
||||
debug!(
|
||||
len = command_text.len(),
|
||||
advanced, "persist: append err record to history.log"
|
||||
@@ -531,8 +524,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn extension_with_tmp_appends_to_existing_extension() {
|
||||
assert_eq!(extension_with_tmp(Path::new("a/b/project.yaml")), "yaml.tmp");
|
||||
assert_eq!(extension_with_tmp(Path::new("a/b/Customers.csv")), "csv.tmp");
|
||||
assert_eq!(
|
||||
extension_with_tmp(Path::new("a/b/project.yaml")),
|
||||
"yaml.tmp"
|
||||
);
|
||||
assert_eq!(
|
||||
extension_with_tmp(Path::new("a/b/Customers.csv")),
|
||||
"csv.tmp"
|
||||
);
|
||||
assert_eq!(extension_with_tmp(Path::new("a/b/lockfile")), "tmp");
|
||||
}
|
||||
|
||||
@@ -600,7 +599,8 @@ mod tests {
|
||||
fn append_history_creates_and_appends() {
|
||||
let dir = tempdir();
|
||||
let p = Persistence::new(dir.path().to_path_buf());
|
||||
p.append_history("create table Foo with pk id(serial)", false).unwrap();
|
||||
p.append_history("create table Foo with pk id(serial)", false)
|
||||
.unwrap();
|
||||
p.append_history("insert into Foo (1)", false).unwrap();
|
||||
let body = fs::read_to_string(dir.path().join(HISTORY_LOG)).unwrap();
|
||||
let lines: Vec<&str> = body.trim_end().lines().collect();
|
||||
|
||||
+117
-35
@@ -261,7 +261,10 @@ fn needs_quoting(s: &str) -> bool {
|
||||
}
|
||||
// Scalar text that looks like a YAML keyword needs quoting
|
||||
// even if every character is safe.
|
||||
if matches!(s, "true" | "false" | "null" | "~" | "yes" | "no" | "on" | "off") {
|
||||
if matches!(
|
||||
s,
|
||||
"true" | "false" | "null" | "~" | "yes" | "no" | "on" | "off"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
s.chars().any(|c| !is_safe_yaml_char(c))
|
||||
@@ -287,13 +290,14 @@ pub(crate) fn parse_schema(body: &str) -> Result<SchemaSnapshot, YamlError> {
|
||||
for t in raw.tables {
|
||||
let mut columns: Vec<ColumnSchema> = Vec::with_capacity(t.columns.len());
|
||||
for c in t.columns {
|
||||
let user_type = c.user_type.parse::<Type>().map_err(|_| {
|
||||
YamlError::UnknownType {
|
||||
let user_type = c
|
||||
.user_type
|
||||
.parse::<Type>()
|
||||
.map_err(|_| YamlError::UnknownType {
|
||||
table: t.name.clone(),
|
||||
column: c.name.clone(),
|
||||
raw: c.user_type.clone(),
|
||||
}
|
||||
})?;
|
||||
})?;
|
||||
columns.push(ColumnSchema {
|
||||
name: c.name,
|
||||
user_type,
|
||||
@@ -308,7 +312,11 @@ pub(crate) fn parse_schema(body: &str) -> Result<SchemaSnapshot, YamlError> {
|
||||
primary_key: t.primary_key,
|
||||
columns,
|
||||
unique_constraints: t.unique_constraints,
|
||||
check_constraints: t.check_constraints.into_iter().map(TableCheck::from).collect(),
|
||||
check_constraints: t
|
||||
.check_constraints
|
||||
.into_iter()
|
||||
.map(TableCheck::from)
|
||||
.collect(),
|
||||
});
|
||||
}
|
||||
let mut relationships: Vec<RelationshipSchema> = Vec::with_capacity(raw.relationships.len());
|
||||
@@ -381,10 +389,7 @@ pub(crate) enum YamlError {
|
||||
impl std::fmt::Display for YamlError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Syntax(msg) => f.write_str(&crate::t!(
|
||||
"persistence.yaml.syntax",
|
||||
detail = msg,
|
||||
)),
|
||||
Self::Syntax(msg) => f.write_str(&crate::t!("persistence.yaml.syntax", detail = msg,)),
|
||||
Self::UnsupportedVersion(v) => f.write_str(&crate::t!(
|
||||
"persistence.yaml.unsupported_version",
|
||||
version = v,
|
||||
@@ -395,10 +400,9 @@ impl std::fmt::Display for YamlError {
|
||||
column = column,
|
||||
raw = raw,
|
||||
)),
|
||||
Self::UnknownAction(raw) => f.write_str(&crate::t!(
|
||||
"persistence.yaml.unknown_action",
|
||||
raw = raw,
|
||||
)),
|
||||
Self::UnknownAction(raw) => {
|
||||
f.write_str(&crate::t!("persistence.yaml.unknown_action", raw = raw,))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,8 +549,22 @@ mod tests {
|
||||
name: "Customers".to_string(),
|
||||
primary_key: vec!["id".to_string()],
|
||||
columns: vec![
|
||||
ColumnSchema { name: "id".to_string(), user_type: Type::Serial, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "Name".to_string(), user_type: Type::Text, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema {
|
||||
name: "id".to_string(),
|
||||
user_type: Type::Serial,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "Name".to_string(),
|
||||
user_type: Type::Text,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
],
|
||||
unique_constraints: Vec::new(),
|
||||
check_constraints: Vec::new(),
|
||||
@@ -555,8 +573,22 @@ mod tests {
|
||||
name: "Orders".to_string(),
|
||||
primary_key: vec!["id".to_string()],
|
||||
columns: vec![
|
||||
ColumnSchema { name: "id".to_string(), user_type: Type::Serial, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "CustId".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema {
|
||||
name: "id".to_string(),
|
||||
user_type: Type::Serial,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "CustId".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
],
|
||||
unique_constraints: Vec::new(),
|
||||
check_constraints: Vec::new(),
|
||||
@@ -798,15 +830,33 @@ indexes:
|
||||
name: "T".to_string(),
|
||||
primary_key: vec![],
|
||||
columns: vec![
|
||||
ColumnSchema { name: "a".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "b".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "c".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema {
|
||||
name: "a".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "b".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "c".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
],
|
||||
unique_constraints: vec![vec!["a".to_string(), "b".to_string()]],
|
||||
check_constraints: vec![
|
||||
TableCheck::unnamed("a < b"),
|
||||
TableCheck::unnamed("b < c"),
|
||||
],
|
||||
check_constraints: vec![TableCheck::unnamed("a < b"), TableCheck::unnamed("b < c")],
|
||||
}],
|
||||
relationships: vec![],
|
||||
indexes: vec![],
|
||||
@@ -830,12 +880,29 @@ indexes:
|
||||
name: "T".to_string(),
|
||||
primary_key: vec!["id".to_string()],
|
||||
columns: vec![
|
||||
ColumnSchema { name: "id".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "qty".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema {
|
||||
name: "id".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "qty".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
],
|
||||
unique_constraints: vec![],
|
||||
check_constraints: vec![
|
||||
TableCheck { name: Some("qty_positive".to_string()), expr: "qty >= 0".to_string() },
|
||||
TableCheck {
|
||||
name: Some("qty_positive".to_string()),
|
||||
expr: "qty >= 0".to_string(),
|
||||
},
|
||||
TableCheck::unnamed("qty < 1000"),
|
||||
],
|
||||
}],
|
||||
@@ -844,7 +911,10 @@ indexes:
|
||||
};
|
||||
let body = serialize_schema(&snap);
|
||||
let parsed = parse_schema(&body).expect("parse schema");
|
||||
assert_eq!(parsed, snap, "named + unnamed table-CHECKs survive the yaml round-trip");
|
||||
assert_eq!(
|
||||
parsed, snap,
|
||||
"named + unnamed table-CHECKs survive the yaml round-trip"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -968,8 +1038,22 @@ relationships:
|
||||
name: "Items".to_string(),
|
||||
primary_key: vec!["a".to_string(), "b".to_string()],
|
||||
columns: vec![
|
||||
ColumnSchema { name: "a".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema { name: "b".to_string(), user_type: Type::Int, unique: false, not_null: false, default: None, check: None },
|
||||
ColumnSchema {
|
||||
name: "a".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
ColumnSchema {
|
||||
name: "b".to_string(),
|
||||
user_type: Type::Int,
|
||||
unique: false,
|
||||
not_null: false,
|
||||
default: None,
|
||||
check: None,
|
||||
},
|
||||
],
|
||||
unique_constraints: Vec::new(),
|
||||
check_constraints: Vec::new(),
|
||||
@@ -1019,12 +1103,10 @@ relationships:
|
||||
let absent = "version: 1\nproject:\n created_at: x\ntables: []\n";
|
||||
assert_eq!(parse_stored_mode(absent), None);
|
||||
|
||||
let explicit_simple =
|
||||
"version: 1\nproject:\n created_at: x\n mode: simple\ntables: []\n";
|
||||
let explicit_simple = "version: 1\nproject:\n created_at: x\n mode: simple\ntables: []\n";
|
||||
assert_eq!(parse_stored_mode(explicit_simple), Some(Mode::Simple));
|
||||
|
||||
let advanced =
|
||||
"version: 1\nproject:\n created_at: x\n mode: advanced\ntables: []\n";
|
||||
let advanced = "version: 1\nproject:\n created_at: x\n mode: advanced\ntables: []\n";
|
||||
assert_eq!(parse_stored_mode(advanced), Some(Mode::Advanced));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user