use std::collections::{BTreeMap, BTreeSet};
use mf2_catalog::Manifest;
use mf2_model::Message;
use crate::corpus::LocaleSource;
#[derive(Debug)]
pub struct Built {
pub manifest: Manifest,
pub source_records: Vec<usize>,
}
impl Built {
pub fn index_of(&self, id: &str) -> Option<usize> {
self.manifest
.ids
.binary_search_by(|i| i.as_str().cmp(id))
.ok()
}
}
pub fn build(
source: &LocaleSource,
models: &[Option<Message<'_>>],
by_id: &BTreeMap<&str, usize>,
functions: &BTreeSet<String>,
) -> Built {
let mut manifest = Manifest {
ids: Vec::with_capacity(by_id.len()),
slots: Vec::with_capacity(by_id.len()),
markup: Vec::with_capacity(by_id.len()),
functions: functions.iter().cloned().collect(),
};
let mut source_records = Vec::with_capacity(by_id.len());
for (id, &record) in by_id {
let (slots, markup) = match models.get(record).and_then(Option::as_ref) {
Some(model) => {
let analysis = mf2_syntax::analyze(model);
(
analysis
.externals
.iter()
.map(|n| n.nfc.to_string())
.collect(),
analysis.markup.iter().map(|n| n.nfc.to_string()).collect(),
)
}
None => (Vec::new(), Vec::new()),
};
manifest.ids.push((*id).to_owned());
manifest.slots.push(slots);
manifest.markup.push(markup);
source_records.push(record);
}
let _ = source;
Built {
manifest,
source_records,
}
}
pub fn functions_of(models: &[Option<Message<'_>>], into: &mut BTreeSet<String>) {
for model in models.iter().flatten() {
for function in &mf2_syntax::analyze(model).functions {
into.insert(function.nfc.to_string());
}
}
}