more recursive docs types (#4028)

* more recursive

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates;

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* add the format

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* get the descriptions again

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Jess Frazelle
2024-09-28 11:51:08 -07:00
committed by GitHub
parent 2a35dd2398
commit 7ed29e2ce4
86 changed files with 120154 additions and 295803 deletions

View File

@ -288,6 +288,7 @@ fn do_stdlib_inner(
name: #arg_name.to_string(),
type_: #ty_string.to_string(),
schema: #schema,
schema_definitions: generator.definitions().clone(),
required: #required,
}
});
@ -343,10 +344,12 @@ fn do_stdlib_inner(
let return_type = if !ret_ty_string.is_empty() || ret_ty_string != "()" {
let ret_ty_string = rust_type_to_openapi_type(&ret_ty_string);
quote! {
let schema = <#return_type_inner>::json_schema(&mut generator);
Some(#docs_crate::StdLibFnArg {
name: "".to_string(),
type_: #ret_ty_string.to_string(),
schema: <#return_type_inner>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}
@ -414,17 +417,19 @@ fn do_stdlib_inner(
vec![#(#tags),*]
}
fn args(&self) -> Vec<#docs_crate::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<#docs_crate::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
// We set this to false so we can recurse them later.
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![#(#arg_types),*]
}
fn return_value(&self) -> Option<#docs_crate::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<#docs_crate::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
// We set this to false so we can recurse them later.
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
#return_type

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for SomeFn {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "data".to_string(),
type_: "Foo".to_string(),
schema: Foo::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <i32>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "i32".to_string(),
schema: <i32>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for SomeFn {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "data".to_string(),
type_: "string".to_string(),
schema: str::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <i32>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "i32".to_string(),
schema: <i32>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -107,26 +107,29 @@ impl crate::docs::StdLibFn for Show {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "[number]".to_string(),
schema: <[f64; 2usize]>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <f64>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: <f64>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Show {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "number".to_string(),
schema: f64::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <f64>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: <f64>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -108,26 +108,29 @@ impl crate::docs::StdLibFn for MyFunc {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "kittycad::types::InputFormat".to_string(),
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <Vec<Sketch>>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "[Sketch]".to_string(),
schema: <Vec<Sketch>>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -108,34 +108,38 @@ impl crate::docs::StdLibFn for LineTo {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![
crate::docs::StdLibFnArg {
name: "data".to_string(),
type_: "LineToData".to_string(),
schema: LineToData::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
},
crate::docs::StdLibFnArg {
name: "sketch".to_string(),
type_: "Sketch".to_string(),
schema: Sketch::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
},
]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <Sketch>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "Sketch".to_string(),
schema: <Sketch>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -107,26 +107,29 @@ impl crate::docs::StdLibFn for Min {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "[number]".to_string(),
schema: <Vec<f64>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <f64>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: <f64>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Show {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "number".to_string(),
schema: <Option<f64>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <f64>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: <f64>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Import {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "kittycad::types::InputFormat".to_string(),
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <f64>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "number".to_string(),
schema: <f64>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Import {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "kittycad::types::InputFormat".to_string(),
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <Vec<Sketch>>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "[Sketch]".to_string(),
schema: <Vec<Sketch>>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Import {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "kittycad::types::InputFormat".to_string(),
schema: <Option<kittycad::types::InputFormat>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: false,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <Vec<Sketch>>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "[Sketch]".to_string(),
schema: <Vec<Sketch>>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,26 +74,29 @@ impl crate::docs::StdLibFn for Show {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![crate::docs::StdLibFnArg {
name: "args".to_string(),
type_: "[number]".to_string(),
schema: <Vec<f64>>::json_schema(&mut generator),
schema_definitions: generator.definitions().clone(),
required: true,
}]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <()>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "()".to_string(),
schema: <()>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -74,21 +74,23 @@ impl crate::docs::StdLibFn for SomeFunction {
vec![]
}
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
fn args(&self, inline_subschemas: bool) -> Vec<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
vec![]
}
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
fn return_value(&self, inline_subschemas: bool) -> Option<crate::docs::StdLibFnArg> {
let mut settings = schemars::gen::SchemaSettings::openapi3();
settings.inline_subschemas = true;
settings.inline_subschemas = inline_subschemas;
let mut generator = schemars::gen::SchemaGenerator::new(settings);
let schema = <i32>::json_schema(&mut generator);
Some(crate::docs::StdLibFnArg {
name: "".to_string(),
type_: "i32".to_string(),
schema: <i32>::json_schema(&mut generator),
schema,
schema_definitions: generator.definitions().clone(),
required: true,
})
}

View File

@ -314,16 +314,23 @@ fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<BTreeMap<String,
// Generate the type markdown files for each argument.
let mut types = BTreeMap::new();
for arg in internal_fn.args() {
for arg in internal_fn.args(false) {
if !arg.is_primitive()? {
add_to_types(&arg.type_, &arg.schema, &mut types)?;
// Add each definition as well.
for (name, definition) in &arg.schema_definitions {
add_to_types(name, definition, &mut types)?;
}
}
}
// Generate the type markdown for the return value.
if let Some(ret) = internal_fn.return_value() {
if let Some(ret) = internal_fn.return_value(false) {
if !ret.is_primitive()? {
add_to_types(&ret.type_, &ret.schema, &mut types)?;
for (name, definition) in &ret.schema_definitions {
add_to_types(name, definition, &mut types)?;
}
}
}
@ -336,7 +343,7 @@ fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<BTreeMap<String,
"tags": internal_fn.tags(),
"examples": examples,
"is_utilities": internal_fn.tags().contains(&"utilities".to_string()),
"args": internal_fn.args().iter().map(|arg| {
"args": internal_fn.args(false).iter().map(|arg| {
json!({
"name": arg.name,
"type_": arg.type_,
@ -344,7 +351,7 @@ fn generate_function(internal_fn: Box<dyn StdLibFn>) -> Result<BTreeMap<String,
"required": arg.required,
})
}).collect::<Vec<_>>(),
"return_value": internal_fn.return_value().map(|ret| {
"return_value": internal_fn.return_value(false).map(|ret| {
json!({
"type_": ret.type_,
"description": ret.description(),
@ -493,6 +500,8 @@ fn generate_type(
// Make sure the name is pascal cased.
if !(name.is_case(convert_case::Case::Pascal)
|| name == "Point3d"
|| name == "Point2d"
|| name == "CircularPattern2dData"
|| name == "CircularPattern3dData"
|| name == "LinearPattern2dData"
@ -594,6 +603,27 @@ fn recurse_and_create_references(
));
};
// If we already have a reference add the metadata to the reference if it has none.
if o.reference.is_some() {
let mut obj = o.clone();
let t = types
.get(name)
.ok_or_else(|| anyhow::anyhow!("Failed to get type: {}", name))?;
let schemars::schema::Schema::Object(to) = t else {
return Err(anyhow::anyhow!(
"Failed to get object schema, should have not been a primitive"
));
};
if let Some(metadata) = obj.metadata.as_mut() {
if metadata.description.is_none() {
metadata.description = to.metadata.as_ref().and_then(|m| m.description.clone());
}
} else {
obj.metadata = to.metadata.clone();
}
return Ok(schemars::schema::Schema::Object(obj));
}
// Check if this is the type we already know about.
for (n, s) in types {
if is_same_schema(schema, s) && name != n && !n.starts_with("[") {

View File

@ -53,6 +53,9 @@ pub struct StdLibFnArg {
/// The schema of the argument.
#[ts(type = "any")]
pub schema: schemars::schema::Schema,
/// The schema definitions for the argument.
#[ts(type = "any")]
pub schema_definitions: schemars::Map<String, schemars::schema::Schema>,
/// If the argument is required.
pub required: bool,
}
@ -86,7 +89,7 @@ impl StdLibFnArg {
}
pub fn description(&self) -> Option<String> {
get_description_string_from_schema(&self.schema.clone())
get_description_string_from_schema(&self.schema.clone(), &self.schema_definitions)
}
}
@ -120,10 +123,10 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
fn tags(&self) -> Vec<String>;
/// The args of the function.
fn args(&self) -> Vec<StdLibFnArg>;
fn args(&self, inline_subschemas: bool) -> Vec<StdLibFnArg>;
/// The return value of the function.
fn return_value(&self) -> Option<StdLibFnArg>;
fn return_value(&self, inline_subschemas: bool) -> Option<StdLibFnArg>;
/// If the function is unpublished.
fn unpublished(&self) -> bool;
@ -147,8 +150,8 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
summary: self.summary(),
description: self.description(),
tags: self.tags(),
args: self.args(),
return_value: self.return_value(),
args: self.args(false),
return_value: self.return_value(false),
unpublished: self.unpublished(),
deprecated: self.deprecated(),
examples: self.examples(),
@ -158,7 +161,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
fn fn_signature(&self) -> String {
let mut signature = String::new();
signature.push_str(&format!("{}(", self.name()));
for (i, arg) in self.args().iter().enumerate() {
for (i, arg) in self.args(false).iter().enumerate() {
if i > 0 {
signature.push_str(", ");
}
@ -169,7 +172,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
}
}
signature.push(')');
if let Some(return_value) = self.return_value() {
if let Some(return_value) = self.return_value(false) {
signature.push_str(&format!(" -> {}", return_value.type_));
}
@ -212,7 +215,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
fn to_autocomplete_snippet(&self) -> Result<String> {
let mut args = Vec::new();
let mut index = 0;
for arg in self.args().iter() {
for arg in self.args(true).iter() {
if let Some((i, arg_str)) = arg.get_autocomplete_snippet(index)? {
index = i + 1;
args.push(arg_str);
@ -238,7 +241,7 @@ pub trait StdLibFn: std::fmt::Debug + Send + Sync {
self.summary()
},
})),
parameters: Some(self.args().into_iter().map(|arg| arg.into()).collect()),
parameters: Some(self.args(true).into_iter().map(|arg| arg.into()).collect()),
active_parameter,
}],
active_signature: Some(0),
@ -308,13 +311,22 @@ impl Clone for Box<dyn StdLibFn> {
}
}
pub fn get_description_string_from_schema(schema: &schemars::schema::Schema) -> Option<String> {
pub fn get_description_string_from_schema(
schema: &schemars::schema::Schema,
definitions: &schemars::Map<String, schemars::schema::Schema>,
) -> Option<String> {
if let schemars::schema::Schema::Object(o) = schema {
if let Some(metadata) = &o.metadata {
if let Some(description) = &metadata.description {
return Some(description.to_string());
}
}
if let Some(reference) = &o.reference {
if let Some(definition) = definitions.get(reference.split('/').last().unwrap_or("")) {
return get_description_string_from_schema(definition, definitions);
}
}
}
None
@ -692,7 +704,7 @@ pub fn completion_item_from_enum_schema(
kind: CompletionItemKind,
) -> Result<CompletionItem> {
// Get the docs for the schema.
let description = get_description_string_from_schema(schema).unwrap_or_default();
let description = get_description_string_from_schema(schema, &Default::default()).unwrap_or_default();
let schemars::schema::Schema::Object(o) = schema else {
anyhow::bail!("expected object schema: {:#?}", schema);
};
@ -754,7 +766,7 @@ mod tests {
#[test]
fn test_deserialize_function() {
let some_function_string = r#"{"type":"StdLib","func":{"name":"line","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{}},"args":[],"unpublished":false,"deprecated":false, "examples": []}}"#;
let some_function_string = r#"{"type":"StdLib","func":{"name":"line","summary":"","description":"","tags":[],"returnValue":{"type":"","required":false,"name":"","schema":{},"schemaDefinitions":{}},"args":[],"unpublished":false,"deprecated":false, "examples": []}}"#;
let some_function: crate::ast::types::Function = serde_json::from_str(some_function_string).unwrap();
assert_eq!(

View File

@ -4,18 +4,16 @@
{{#if $ref}}
{{pretty_ref $ref}}
{{else if enum}}
**enum:** {{pretty_enum enum}}
{{else if type}}
**Type:** `{{type}}`{{~ #if format }} (`{{format}}`){{/if ~}}
{{/if}}
{{#if $schema}}
**Schema:** `{{$schema}}`
{{/if}}
{{#if enum}}
**enum:** {{pretty_enum enum}}
{{else if type}}
**Type:** `{{type}}`
{{/if}}
{{#if items}}
{{>array}}
{{/if}}

View File

@ -41,9 +41,10 @@ fn lint_too_many_args_std_lib_function(f: Box<dyn StdLibFn>, exp: &CallExpressio
return Ok(findings);
}
if exp.arguments.len() > f.args().len() {
let fn_args_len = f.args(false).len();
if exp.arguments.len() > fn_args_len {
findings.push(Z0002.at(
format!("expected {} arguments, found {}", f.args().len(), exp.arguments.len()),
format!("expected {} arguments, found {}", fn_args_len, exp.arguments.len()),
SourceRange::new(exp.start, exp.end),
));
}

View File

@ -1651,7 +1651,7 @@ fn fn_call(i: TokenSlice) -> PResult<CallExpression> {
let args = arguments(i)?;
if let Some(std_fn) = crate::std::get_stdlib_fn(&fn_name.name) {
// Type check the arguments.
for (i, spec_arg) in std_fn.args().iter().enumerate() {
for (i, spec_arg) in std_fn.args(false).iter().enumerate() {
let Some(arg) = &args.get(i) else {
// The executor checks the number of arguments, so we don't need to check it here.
continue;