use alloc::{string::String, vec::Vec};
use crate::{Error, Rule, Style, check, json, rule::Text};
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Grammar {
pub(crate) scope_name: Text,
pub(crate) name: Option<Text>,
pub(crate) file_types: Vec<Text>,
pub(crate) first_line_match: Option<Text>,
pub(crate) injection_selector: Option<Text>,
pub(crate) patterns: Vec<Rule>,
pub(crate) repository: Vec<(Text, Rule)>,
pub(crate) injections: Vec<(Text, Rule)>,
}
impl Grammar {
#[must_use]
pub fn new(scope_name: impl Into<Text>) -> Grammar {
Grammar {
scope_name: scope_name.into(),
name: None,
file_types: Vec::new(),
first_line_match: None,
injection_selector: None,
patterns: Vec::new(),
repository: Vec::new(),
injections: Vec::new(),
}
}
#[must_use]
pub fn scope_name(&self) -> &str {
&self.scope_name
}
#[must_use]
pub fn name(mut self, name: impl Into<Text>) -> Grammar {
self.name = Some(name.into());
self
}
#[must_use]
pub fn file_type(mut self, extension: impl Into<Text>) -> Grammar {
self.file_types.push(extension.into());
self
}
#[must_use]
pub fn first_line_match(mut self, regex: impl Into<Text>) -> Grammar {
self.first_line_match = Some(regex.into());
self
}
#[must_use]
pub fn injection_selector(mut self, selector: impl Into<Text>) -> Grammar {
self.injection_selector = Some(selector.into());
self
}
#[must_use]
pub fn pattern(mut self, rule: impl Into<Rule>) -> Grammar {
self.patterns.push(rule.into());
self
}
#[must_use]
pub fn repository(mut self, name: impl Into<Text>, rule: impl Into<Rule>) -> Grammar {
self.repository.push((name.into(), rule.into()));
self
}
#[must_use]
pub fn injection(mut self, selector: impl Into<Text>, rule: impl Into<Rule>) -> Grammar {
self.injections.push((selector.into(), rule.into()));
self
}
pub fn validate(&self) -> Result<(), Error> {
check::check(self).map(|_| ())
}
pub fn to_json(&self) -> Result<String, Error> {
let mut out = String::new();
self.write_json(&mut out, Style::Pretty)?;
Ok(out)
}
pub fn to_json_compact(&self) -> Result<String, Error> {
let mut out = String::new();
self.write_json(&mut out, Style::Compact)?;
Ok(out)
}
pub fn write_json(&self, out: &mut String, style: Style) -> Result<(), Error> {
let checked = check::check(self)?;
json::write(self, &checked, out, style == Style::Pretty);
Ok(())
}
}