jsonpiler 0.10.4

a Json syntax programming language for Windows
Documentation
mod diagnostic;
mod find_symbol;
mod text_document;
use crate::prelude::*;
use std::process::exit;
impl Server {
  #[expect(clippy::print_stderr)]
  pub(crate) fn eval_method(&mut self, method: &str, params: JsonNoPos, id_opt: Option<IdKind>) {
    macro_rules! unwrap_id {
      ($id_opt:expr) => {{
        let Some(id) = $id_opt else {
          eprintln!("Missing id");
          return;
        };
        id
      }};
    }
    match method {
      "initialize" => self.m_initialize(unwrap_id!(id_opt)),
      "initialized" => (),
      "textDocument/didOpen" => self.m_did_open(params),
      "textDocument/didChange" => self.m_did_change(params),
      "textDocument/didSave" => (),
      "textDocument/completion" => self.m_completion(params, unwrap_id!(id_opt)),
      "textDocument/definition" => self.m_definition(params, unwrap_id!(id_opt)),
      "textDocument/references" => self.m_references(params, unwrap_id!(id_opt)),
      "textDocument/formatting" => self.m_formatting(params, unwrap_id!(id_opt)),
      "textDocument/hover" => self.m_hover(params, unwrap_id!(id_opt)),
      "textDocument/didClose" => self.m_did_close(params),
      "shutdown" => self.m_shutdown(unwrap_id!(id_opt)),
      "exit" => exit(if self.shutdown { 0 } else { 1 }),
      _ => {
        eprintln!("Method not found");
        if let Some(id) = id_opt {
          self.error(id, -32601, "Method not found");
        }
      }
    }
  }
  pub(crate) fn m_completion(&mut self, mut params: JsonNoPos, id: IdKind) {
    let Some(_uri) = (|| params.take("textDocument")?.take("uri")?.into_str())() else {
      self.error(id, -32602, "Invalid params");
      return;
    };
    let Some(_position) = params.get("position") else {
      self.error(id, -32602, "Invalid params");
      return;
    };
    let (trigger_kind, trigger_character) = params
      .get("context")
      .and_then(|context| {
        context.get_int("triggerKind").map(|trigger_kind| {
          (trigger_kind, context.get("triggerCharacter").and_then(JsonNoPos::as_str))
        })
      })
      .unwrap_or((1, None));
    let items = ArrayN(if trigger_kind == 2 {
      match trigger_character {
        Some(":") => ["Int", "Float", "Bool", "Str", "Null"]
          .into_iter()
          .map(|ty| {
            ObjectN(vec![
              ("label".into(), StrN(ty.into())),
              ("kind".into(), IntN(7)),
              ("insertText".into(), StrN(format!(" {}; ", ty))),
            ])
          })
          .collect::<Vec<_>>(),
        _ => vec![],
      }
    } else {
      vec![]
    });
    self.response(id, items);
  }
  pub(crate) fn m_initialize(&mut self, id: IdKind) {
    use super::build_doc_cache;
    self.docs = Some(build_doc_cache());
    let mut capabilities = vec![
      ("textDocumentSync".into(), IntN(2)),
      (
        "completionProvider".into(),
        ObjectN(vec![("triggerCharacters".into(), ArrayN(vec![StrN(":".into())]))]),
      ),
    ];
    const PROVIDERS: [&str; 4] = ["documentFormatting", "hover", "references", "definition"];
    for provider in PROVIDERS {
      capabilities.push((format!("{}Provider", provider), BoolN(true)));
    }
    self.response(id, ObjectN(vec![("capabilities".into(), ObjectN(capabilities))]));
  }
  pub(crate) fn m_shutdown(&mut self, id: IdKind) {
    self.response(id, NullN);
    self.shutdown = true;
  }
}