coven_format/
write_sources.rs1use crate::error::{require, Error, Rule};
4use crate::value::{name, positive, row};
5use crate::wire::wire_struct;
6use coven_merge::{RowId, WriteId, WritePast};
7use std::collections::BTreeMap;
8
9#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
11pub struct ChangeId {
12 pub write: WriteId,
14 pub row: RowId,
16}
17wire_struct!(ChangeId, write, row);
18
19#[derive(Clone, Debug, PartialEq, Eq)]
21pub struct CellSource {
22 pub change: ChangeId,
24 pub column: String,
26}
27wire_struct!(CellSource, change, column => crate::wire::get_name);
28
29#[derive(Clone, Debug, Default, PartialEq, Eq)]
31pub struct WriteSources {
32 pub generation: Option<ChangeId>,
34 pub setters: BTreeMap<String, CellSource>,
38}
39wire_struct!(WriteSources, generation, setters => crate::wire::get_name_map);
40
41impl WriteSources {
42 pub fn changes(&self) -> impl Iterator<Item = &ChangeId> {
45 self.generation.iter().chain(self.setters.values().map(|s| &s.change))
46 }
47
48 pub(crate) fn validate(&self, generation: u64) -> Result<(), Error> {
49 require(
50 self.generation.is_none() == (generation == 0),
51 "generation source",
52 Rule::Generation,
53 )?;
54 for source in self.changes() {
55 positive(source.write.number)?;
56 row(&source.row)?;
57 }
58 for (column, source) in &self.setters {
59 name(column)?;
60 name(&source.column)?;
61 }
62 Ok(())
63 }
64
65 pub fn validate_past(&self, past: &impl WritePast) -> Result<(), Error> {
68 require(self.changes().all(|s| past.contains(&s.write)), "source read", Rule::Coverage)
69 }
70}