Skip to main content

lex_babel/formats/lex/
mod.rs

1//! Lex format implementation
2//!
3//! This module implements the Format trait for Lex itself, treating Lex
4//! as just another format in the system. This creates a uniform API where
5//! Lex can be converted to/from other formats using the same interface.
6
7use crate::error::FormatError;
8use crate::format::Format;
9use lex_core::lex::ast::Document;
10use lex_core::lex::transforms::standard::STRING_TO_AST;
11
12pub mod formatting_rules;
13pub mod serializer;
14
15use formatting_rules::FormattingRules;
16use serializer::LexSerializer;
17///
18/// Parses Lex source text into a Document AST by delegating to lex-parser.
19/// Serialization is implemented via LexSerializer.
20#[derive(Default)]
21pub struct LexFormat {
22    rules: FormattingRules,
23}
24
25impl LexFormat {
26    pub fn new(rules: FormattingRules) -> Self {
27        Self { rules }
28    }
29}
30
31impl Format for LexFormat {
32    fn name(&self) -> &str {
33        "lex"
34    }
35
36    fn description(&self) -> &str {
37        "Lex document format"
38    }
39
40    fn file_extensions(&self) -> &[&str] {
41        &["lex"]
42    }
43
44    fn supports_parsing(&self) -> bool {
45        true
46    }
47
48    fn supports_serialization(&self) -> bool {
49        true
50    }
51
52    fn parse(&self, source: &str) -> Result<Document, FormatError> {
53        STRING_TO_AST
54            .run(source.to_string())
55            .map_err(|e| FormatError::ParseError(e.to_string()))
56    }
57
58    fn serialize(&self, doc: &Document) -> Result<String, FormatError> {
59        let serializer = LexSerializer::new(self.rules.clone());
60        serializer
61            .serialize(doc)
62            .map_err(FormatError::SerializationError)
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use lex_core::lex::ast::{ContentItem, Paragraph};
70
71    #[test]
72    fn test_lex_format_name() {
73        let format = LexFormat::default();
74        assert_eq!(format.name(), "lex");
75    }
76
77    #[test]
78    fn test_lex_format_supports_parsing() {
79        let format = LexFormat::default();
80        assert!(format.supports_parsing());
81        assert!(format.supports_serialization());
82    }
83
84    #[test]
85    fn test_lex_format_parse_simple() {
86        let format = LexFormat::default();
87        let source = "Hello world\n";
88
89        let result = format.parse(source);
90        assert!(result.is_ok());
91
92        let doc = result.unwrap();
93        assert_eq!(doc.root.children.len(), 1);
94
95        match &doc.root.children[0] {
96            ContentItem::Paragraph(_) => {}
97            _ => panic!("Expected paragraph"),
98        }
99    }
100
101    #[test]
102    fn test_lex_format_parse_session() {
103        let format = LexFormat::default();
104        let source = "Introduction:\n    Welcome to the guide\n";
105
106        let result = format.parse(source);
107        assert!(result.is_ok());
108
109        let doc = result.unwrap();
110        // Just verify that something was parsed successfully
111        // The exact structure depends on the parser implementation
112        assert!(!doc.root.children.is_empty());
113    }
114
115    #[test]
116    fn test_lex_format_parse_error() {
117        let format = LexFormat::default();
118        // Create invalid Lex that would cause a parse error
119        // Note: Current parser is very permissive, so this might not fail
120        // But the test shows the error handling works
121        let source = "";
122
123        let result = format.parse(source);
124        // Empty document should parse successfully
125        assert!(result.is_ok());
126    }
127
128    #[test]
129    fn test_lex_format_serialize_supported() {
130        let format = LexFormat::default();
131        let doc = Document::with_content(vec![ContentItem::Paragraph(Paragraph::from_line(
132            "Test".to_string(),
133        ))]);
134
135        let result = format.serialize(&doc);
136        assert!(result.is_ok());
137        assert_eq!(result.unwrap(), "Test\n");
138    }
139}