use crate::messages::Refusal;
pub use vla_lang::projection::{Projection, Window};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Seam {
pub name: &'static str,
pub entrance: &'static str,
pub oracle: &'static str,
pub implementations: &'static [&'static str],
pub deferred_to: &'static str,
}
pub const SEAMS: [Seam; 6] = [
Seam {
name: "sentences",
entrance: "a phrasebook file (.vla) with its test: proofs, loaded through api::vocab_gate",
oracle: "frazaro prove passes every proof; the translate and refusal goldens hold",
implementations: &["the phrasebooks a door loads, english.vla first"],
deferred_to: "",
},
Seam {
name: "paragraphs",
entrance: "a library of sentences with named slots, imported by a Use sentence",
oracle: "the build golden, and the stamp hashing every file used",
implementations: &[],
deferred_to: "G-USE",
},
Seam {
name: "engines",
entrance: "an implementation of kernel::Engine under a head-table symbol",
oracle: "a proof file of its kind, with clingo beside it where it applies",
implementations: &[],
deferred_to: "PORT.9",
},
Seam {
name: "formats and hosts",
entrance: "an implementation of reflect::Source to read, a writer beside it, and a kernel::HostProfile per door",
oracle: "the reflect, diff and audit goldens for a reader; the build golden for a writer",
implementations: &["xlsx (OOXML), read and written", "ods (OpenDocument), read"],
deferred_to: "",
},
Seam {
name: "projections",
entrance: "an implementation of vla_lang::projection::Projection",
oracle: "a view golden per projection",
implementations: &["grid, the view record of one window (view::Grid)"],
deferred_to: "",
},
Seam {
name: "functions",
entrance: "a function registered into vla_lang::calc::Library, with the fixture a host saved that shows it (excel::library)",
oracle: "the recalc golden: the fixture's cached values agree (check_recalc_golden.ps1)",
implementations: &[
"the language's fourteen day-one functions (vla_lang::calc::library)",
"Excel's library, the declared subset by measurement (excel::SUBSET)",
],
deferred_to: "",
},
];
pub fn seams() -> &'static [Seam] {
&SEAMS
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Format {
pub name: &'static str,
pub extension: &'static str,
pub reads: bool,
pub writes: bool,
}
pub const FORMATS: [Format; 2] = [
Format {
name: "OOXML",
extension: "xlsx",
reads: true,
writes: true,
},
Format {
name: "OpenDocument",
extension: "ods",
reads: true,
writes: false,
},
];
pub trait Engine {
type Table;
fn head(&self) -> &str;
fn proof_kind(&self) -> &str;
fn run(&self, tables: &[Self::Table]) -> Result<Self::Table, Refusal>;
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct HostProfile {
pub door: &'static str,
pub forms: &'static [&'static str],
pub scaffold: &'static [&'static str],
pub refuses_with: &'static str,
}
pub const FILE_DOOR: HostProfile = HostProfile {
door: "file",
forms: &[
"at-line",
"begin",
"dim",
"on-error",
"label",
"exit-sub",
"exit-function",
"set!",
"if",
".",
],
scaffold: &["vla-report-error", "vlaensuresheet"],
refuses_with: "build-not-representable",
};
pub const HOST_PROFILES: [HostProfile; 1] = [FILE_DOOR];
#[cfg(test)]
mod tests {
use super::*;
use crate::headtable;
use crate::reflect;
const FIXTURE_XLSX: &[u8] = include_bytes!("../../scripts/reflect/fixture.xlsx");
const FIXTURE_ODS: &[u8] = include_bytes!("../../scripts/reflect/opendocument.ods");
#[test]
fn six_seams_each_with_an_entrance_and_an_oracle() {
assert_eq!(seams().len(), 6);
let names: Vec<&str> = seams().iter().map(|s| s.name).collect();
assert_eq!(
names,
[
"sentences",
"paragraphs",
"engines",
"formats and hosts",
"projections",
"functions"
]
);
for s in seams() {
assert!(!s.entrance.is_empty(), "{} names no entrance", s.name);
assert!(!s.oracle.is_empty(), "{} names no oracle", s.name);
assert!(
!s.implementations.is_empty() || !s.deferred_to.is_empty(),
"{} has neither an implementation nor the item that lands one",
s.name
);
}
}
#[test]
fn the_engines_seam_is_empty_today_and_the_projections_seam_has_its_grid() {
let engines = seams().iter().find(|s| s.name == "engines").unwrap();
assert!(engines.implementations.is_empty());
assert_eq!(engines.deferred_to, "PORT.9");
let projections = seams().iter().find(|s| s.name == "projections").unwrap();
assert_eq!(projections.implementations.len(), 1);
assert_eq!(projections.deferred_to, "");
assert_eq!(crate::view::Grid::default().name(), "grid");
assert!(projections.implementations[0].starts_with("grid"));
let paragraphs = seams().iter().find(|s| s.name == "paragraphs").unwrap();
assert_eq!(paragraphs.deferred_to, "G-USE");
}
#[test]
fn the_formats_registry_matches_the_readers_and_the_writer() {
assert_eq!(FORMATS.len(), 2);
assert!(reflect::open(FIXTURE_XLSX, "fixture.xlsx").is_ok());
assert!(reflect::open(FIXTURE_ODS, "opendocument.ods").is_ok());
let readers: Vec<&str> = FORMATS
.iter()
.filter(|f| f.reads)
.map(|f| f.extension)
.collect();
assert_eq!(readers, ["xlsx", "ods"]);
let writers: Vec<&str> = FORMATS
.iter()
.filter(|f| f.writes)
.map(|f| f.extension)
.collect();
assert_eq!(writers, ["xlsx"], "the one writer is the OOXML writer");
let formats = seams()
.iter()
.find(|s| s.name == "formats and hosts")
.unwrap();
assert_eq!(formats.implementations.len(), FORMATS.len());
}
#[test]
fn the_file_door_holds_only_core_forms_and_refuses_from_the_catalogue() {
assert_eq!(HOST_PROFILES.len(), 1);
assert_eq!(FILE_DOOR.door, "file");
for sym in FILE_DOOR.forms {
let canonical = headtable::resolve_head_alias(sym);
assert!(
headtable::row(&canonical).is_some(),
"{sym} is not a form of the head table"
);
}
for call in FILE_DOOR.scaffold {
assert!(
headtable::row(call).is_none(),
"{call} is a scaffold call, not a core form"
);
}
assert_eq!(FILE_DOOR.refuses_with, "build-not-representable");
}
#[test]
fn the_projection_trait_is_the_language_s() {
let w: vla_lang::projection::Window = Window {
sheet: "Model".to_string(),
range: crate::sheet::parse_a1_range("A1:F20").unwrap(),
};
assert_eq!(w.range.cells(), 120);
}
}