Files
windmill/backend/parsers/windmill-parser-graphql/src/lib.rs
T
HugoCasa 8a1f9a7c6a feat: add native powershell support (#2025)
* feat: add powershell support

* fix: lang build
2023-08-10 13:19:50 +00:00

111 lines
3.2 KiB
Rust

#![allow(non_snake_case)] // TODO: switch to parse_* function naming
use anyhow::anyhow;
use regex::Regex;
use serde_json::json;
use windmill_parser::{Arg, MainArgSignature, Typ};
pub fn parse_graphql_sig(code: &str) -> anyhow::Result<MainArgSignature> {
let parsed = parse_graphql_file(&code)?;
if let Some(x) = parsed {
let args = x;
Ok(MainArgSignature { star_args: false, star_kwargs: false, args })
} else {
Err(anyhow!("Error parsing sql".to_string()))
}
}
lazy_static::lazy_static! {
static ref RE_ARG_GRAPHQL: Regex = Regex::new(r#"\$(\w+)\s*:\s*(?:(\w+)!?|\[(\w+)!?\])!?\s*(?:=\s*(\w+)\s*)?"#).unwrap();
}
fn parse_graphql_file(code: &str) -> anyhow::Result<Option<Vec<Arg>>> {
let mut args: Vec<Arg> = vec![];
for cap in RE_ARG_GRAPHQL.captures_iter(code) {
let name = cap.get(1).map(|x| x.as_str().to_string()).unwrap();
let mut typ = cap.get(2).map(|x| x.as_str().to_string());
let parsed_typ = if typ.is_none() {
let inner_typ = cap.get(3).map(|x| x.as_str().to_string());
typ = inner_typ.clone().map(|x| format!("[{}]", x.to_string()));
Typ::List(Box::new(parse_graphql_typ(inner_typ.unwrap().as_str())))
} else {
parse_graphql_typ(typ.clone().unwrap().as_str())
};
let default = cap.get(4).map(|x| x.as_str().to_string());
let has_default = default.is_some();
let parsed_default = default.and_then(|x| match parsed_typ {
Typ::Int => x.parse::<i64>().ok().map(|x| json!(x)),
Typ::Float => x.parse::<f64>().ok().map(|x| json!(x)),
_ => Some(json!(x)),
});
args.push(Arg {
name,
typ: parsed_typ,
default: parsed_default,
otyp: Some(typ.unwrap()),
has_default,
});
}
Ok(Some(args))
}
pub fn parse_graphql_typ(typ: &str) -> Typ {
match typ {
"String" | "ID" => Typ::Str(None),
"Int" => Typ::Int,
"Boolean" => Typ::Bool,
"Float" => Typ::Float,
_ => Typ::Object(vec![]),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_graphql_sig() -> anyhow::Result<()> {
let code = r#"
query($s: String, $arr: [String]) {
books {
title
}
}
"#;
//println!("{}", serde_json::to_string()?);
assert_eq!(
parse_graphql_sig(code)?,
MainArgSignature {
star_args: false,
star_kwargs: false,
args: vec![
Arg {
otyp: Some("String".to_string()),
name: "s".to_string(),
typ: Typ::Str(None),
default: None,
has_default: false
},
Arg {
otyp: Some("[String]".to_string()),
name: "arr".to_string(),
typ: Typ::List(Box::new(Typ::Str(None))),
default: None,
has_default: false
},
]
}
);
Ok(())
}
}