isothrum_compiler/
compiled.rs1use isoloom_spec::Spec;
4
5use crate::document::{ProvisionDoc, SpecDoc};
6use crate::draft::Draft;
7use crate::{Error, ProjectFile, Result, Topology, cables, lans, machines, project, routers, starters, vlans};
8
9#[derive(Debug, Clone, PartialEq)]
12pub struct Compiled {
13 yaml: String,
14 spec: Spec,
15 files: Vec<ProjectFile>,
16}
17
18impl Compiled {
19 #[must_use]
21 pub fn yaml(&self) -> &str {
22 &self.yaml
23 }
24
25 #[must_use]
27 pub fn spec(&self) -> &Spec {
28 &self.spec
29 }
30
31 #[must_use]
35 pub fn files(&self) -> &[ProjectFile] {
36 &self.files
37 }
38
39 #[must_use]
41 pub fn into_parts(self) -> (String, Spec, Vec<ProjectFile>) {
42 (self.yaml, self.spec, self.files)
43 }
44}
45
46pub fn compile(topo: &Topology) -> Result<Compiled> {
54 cables::check_count(topo)?;
55 vlans::check_switch_names(topo)?;
56 let mut draft = Draft::default();
57 machines::add(topo, &mut draft)?;
58 lans::address(topo, &mut draft)?;
59 cables::allocate(topo, &mut draft)?;
60 routers::add_reach_rules(&mut draft);
61 routers::cisco_gateways(topo, &mut draft);
62 vlans::nest(topo, &mut draft);
63 let doc = SpecDoc {
64 version: 1,
65 name: topo.name.clone(),
66 networks: draft.networks,
67 reach: draft.reach,
68 machines: draft.machines,
69 provision: draft.controller.iter().map(ProvisionDoc::from).collect(),
70 };
71 let yaml = serde_yaml_ng::to_string(&doc).map_err(Error::Yaml)?;
72 let spec = isoloom_spec::syntax::parse(&yaml).map_err(Error::Unreadable)?;
73 let mut files = project::config_files(topo);
74 starters::add_starters(&mut files, &spec, &draft.controller);
75 Ok(Compiled { yaml, spec, files })
76}