1use crate::graph::Graph;
2use crate::parser::ast::{Ast, AstNode, FileMetadata};
3use crate::primitives::{Entity, Resource};
4
5const DEFAULT_NAMESPACE: &str = "default";
6
7fn map_domain(namespace: &str) -> Option<String> {
8 if namespace != DEFAULT_NAMESPACE {
9 Some(namespace.to_string())
10 } else {
11 None
12 }
13}
14
15impl Graph {
16 pub fn to_ast(&self) -> Ast {
17 let mut declarations = Vec::new();
18
19 let mut entities: Vec<&Entity> = self.entities.values().collect();
21 entities.sort_by(|a, b| {
22 a.name()
23 .cmp(b.name())
24 .then_with(|| a.namespace().cmp(b.namespace()))
25 });
26 for entity in entities {
27 let node = AstNode::Entity {
28 name: entity.name().to_string(),
29 version: entity.version().map(|v| v.to_string()),
30 annotations: Default::default(),
31 domain: map_domain(entity.namespace()),
32 };
33 declarations.push(crate::parser::ast::Spanned {
34 node,
35 line: 0,
36 column: 0,
37 });
38 }
39
40 let mut resources: Vec<&Resource> = self.resources.values().collect();
42 resources.sort_by(|a, b| {
43 a.name()
44 .cmp(b.name())
45 .then_with(|| a.namespace().cmp(b.namespace()))
46 });
47 for resource in resources {
48 let node = AstNode::Resource {
49 name: resource.name().to_string(),
50 annotations: Default::default(),
51 unit_name: None,
52 domain: map_domain(resource.namespace()),
53 };
54 declarations.push(crate::parser::ast::Spanned {
55 node,
56 line: 0,
57 column: 0,
58 });
59 }
60
61 Ast {
62 metadata: FileMetadata::default(),
63 declarations,
64 }
65 }
66}