Skip to main content

yaml_edit/nodes/
directive.rs

1use super::{Lang, SyntaxNode};
2use crate::lex::SyntaxKind;
3use rowan::ast::AstNode;
4use rowan::GreenNodeBuilder;
5
6ast_node!(Directive, DIRECTIVE, "A YAML directive like %YAML 1.2");
7
8impl Directive {
9    /// Get the full directive text (e.g., "%YAML 1.2")
10    pub fn text(&self) -> String {
11        self.0.text().to_string()
12    }
13
14    /// Get the directive name (e.g., "YAML" from "%YAML 1.2")
15    pub fn name(&self) -> Option<String> {
16        let text = self.text();
17        if let Some(directive_content) = text.strip_prefix('%') {
18            directive_content
19                .split_whitespace()
20                .next()
21                .map(|s| s.to_string())
22        } else {
23            None
24        }
25    }
26
27    /// Get the directive value (e.g., "1.2" from "%YAML 1.2")
28    pub fn value(&self) -> Option<String> {
29        let text = self.text();
30        if let Some(directive_content) = text.strip_prefix('%') {
31            let parts: Vec<&str> = directive_content.split_whitespace().collect();
32            if parts.len() > 1 {
33                Some(parts[1..].join(" "))
34            } else {
35                None
36            }
37        } else {
38            None
39        }
40    }
41
42    /// Check if this is a YAML version directive
43    pub fn is_yaml_version(&self) -> bool {
44        self.name().as_deref() == Some("YAML")
45    }
46
47    /// Check if this is a TAG directive
48    pub fn is_tag(&self) -> bool {
49        self.name().as_deref() == Some("TAG")
50    }
51
52    /// Create a new YAML version directive
53    pub fn new_yaml_version(version: &str) -> Self {
54        let directive_text = format!("%YAML {version}");
55        let mut builder = GreenNodeBuilder::new();
56        builder.start_node(SyntaxKind::DIRECTIVE.into());
57        builder.token(SyntaxKind::DIRECTIVE.into(), &directive_text);
58        builder.finish_node();
59        Directive(SyntaxNode::new_root_mut(builder.finish()))
60    }
61
62    /// Create a new TAG directive
63    pub fn new_tag(handle: &str, prefix: &str) -> Self {
64        let directive_text = format!("%TAG {handle} {prefix}");
65        let mut builder = GreenNodeBuilder::new();
66        builder.start_node(SyntaxKind::DIRECTIVE.into());
67        builder.token(SyntaxKind::DIRECTIVE.into(), &directive_text);
68        builder.finish_node();
69        Directive(SyntaxNode::new_root_mut(builder.finish()))
70    }
71}