Skip to main content

zen_expression/nl/
mod.rs

1pub(crate) mod project;
2pub mod token;
3
4pub use token::{EditHint, EnumOption, NlToken, NlTokenKind, OpChoice, OpSym, TypeTag, WordSym};
5
6use serde::Serialize;
7use std::rc::Rc;
8
9use crate::intellisense::diagnostic::Diagnostic;
10use crate::intellisense::NlLabelResolver;
11use crate::variable::VariableType;
12
13pub fn encode_string(value: &str) -> Option<String> {
14    if !value.contains('"') {
15        Some(format!("\"{value}\""))
16    } else if !value.contains('\'') {
17        Some(format!("'{value}'"))
18    } else {
19        None
20    }
21}
22
23pub(crate) fn enum_options(
24    name: Option<&str>,
25    values: &[Rc<str>],
26    labels: Option<&NlLabelResolver>,
27) -> Vec<EnumOption> {
28    values
29        .iter()
30        .map(|v| EnumOption {
31            label: labels
32                .zip(name)
33                .and_then(|(resolve, n)| resolve(n, v))
34                .filter(|l| !l.is_empty())
35                .unwrap_or_else(|| v.to_string()),
36            source: encode_string(v),
37        })
38        .collect()
39}
40
41pub(crate) fn subject_enum_options(
42    subject: &VariableType,
43    labels: Option<&NlLabelResolver>,
44) -> Option<Vec<EnumOption>> {
45    match subject {
46        VariableType::Enum(name, values) => Some(enum_options(name.as_deref(), values, labels)),
47        VariableType::Nullable(inner) | VariableType::Array(inner) => {
48            subject_enum_options(inner, labels)
49        }
50        _ => None,
51    }
52}
53
54#[derive(Debug, Clone)]
55pub struct NlRequest {
56    pub id: String,
57    pub expression: String,
58    pub unary: bool,
59    pub subject_type: Option<VariableType>,
60}
61
62#[derive(Debug, Clone, Serialize)]
63#[serde(rename_all = "camelCase")]
64pub struct NlResult {
65    pub id: String,
66    pub tokens: Vec<NlToken>,
67    pub enums: Vec<Vec<EnumOption>>,
68    pub diagnostics: Vec<Diagnostic>,
69    #[serde(skip)]
70    pub subject_type: Option<VariableType>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub subject_options: Option<Vec<EnumOption>>,
73}