Patterns 2d 3d (#1701)
* refactor Signed-off-by: Jess Frazelle <github@jessfraz.com> * pattern2d and 3d Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix derive docs more Signed-off-by: Jess Frazelle <github@jessfraz.com> * fixes Signed-off-by: Jess Frazelle <github@jessfraz.com> * fix Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "derive-docs"
|
||||
description = "A tool for generating documentation from Rust derive macros"
|
||||
version = "0.1.9"
|
||||
version = "0.1.10"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/KittyCAD/modeling-app"
|
||||
|
@ -223,31 +223,59 @@ fn do_stdlib_inner(
|
||||
}
|
||||
}
|
||||
|
||||
let ret_ty = ast.sig.output.clone();
|
||||
let ret_ty_string = ret_ty
|
||||
.into_token_stream()
|
||||
.to_string()
|
||||
.replace("-> ", "")
|
||||
.replace("Result < ", "")
|
||||
.replace(", KclError >", "");
|
||||
let return_type = if !ret_ty_string.is_empty() {
|
||||
let ret_ty_string = if ret_ty_string.starts_with("Box <") {
|
||||
ret_ty_string
|
||||
.trim_start_matches("Box <")
|
||||
.trim_end_matches(' ')
|
||||
.trim_end_matches('>')
|
||||
.trim()
|
||||
.to_string()
|
||||
} else {
|
||||
ret_ty_string.trim().to_string()
|
||||
};
|
||||
let ret_ty_ident = format_ident!("{}", ret_ty_string);
|
||||
let return_type_inner = match &ast.sig.output {
|
||||
syn::ReturnType::Default => quote! { () },
|
||||
syn::ReturnType::Type(_, ty) => {
|
||||
// Get the inside of the result.
|
||||
match &**ty {
|
||||
syn::Type::Path(syn::TypePath { path, .. }) => {
|
||||
let path = &path.segments;
|
||||
if path.len() == 1 {
|
||||
let seg = &path[0];
|
||||
if seg.ident == "Result" {
|
||||
if let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments {
|
||||
args,
|
||||
..
|
||||
}) = &seg.arguments
|
||||
{
|
||||
if args.len() == 2 || args.len() == 1 {
|
||||
let mut args = args.iter();
|
||||
let ok = args.next().unwrap();
|
||||
if let syn::GenericArgument::Type(ty) = ok {
|
||||
let ty = unbox(unbox_vec(ty.clone()));
|
||||
quote! { #ty }
|
||||
} else {
|
||||
quote! { () }
|
||||
}
|
||||
} else {
|
||||
quote! { () }
|
||||
}
|
||||
} else {
|
||||
quote! { () }
|
||||
}
|
||||
} else {
|
||||
let ty = unbox(unbox_vec(*ty.clone()));
|
||||
quote! { #ty }
|
||||
}
|
||||
} else {
|
||||
quote! { () }
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
quote! { () }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let ret_ty_string = return_type_inner.to_string().replace(' ', "");
|
||||
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! {
|
||||
Some(#docs_crate::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: #ret_ty_string.to_string(),
|
||||
schema: #ret_ty_ident::json_schema(&mut generator),
|
||||
schema: <#return_type_inner>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
@ -547,6 +575,93 @@ fn parse_array_type(type_name: &str) -> Option<(&str, usize)> {
|
||||
Some((inner_type.as_str(), length))
|
||||
}
|
||||
|
||||
// Unbox a syn::Type that is boxed to the inner object.
|
||||
fn unbox(t: syn::Type) -> syn::Type {
|
||||
match t {
|
||||
syn::Type::Path(syn::TypePath { ref path, .. }) => {
|
||||
let path = &path.segments;
|
||||
if path.len() == 1 {
|
||||
let seg = &path[0];
|
||||
if seg.ident == "Box" {
|
||||
if let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { args, .. }) =
|
||||
&seg.arguments
|
||||
{
|
||||
if args.len() == 1 {
|
||||
let mut args = args.iter();
|
||||
let ok = args.next().unwrap();
|
||||
if let syn::GenericArgument::Type(ty) = ok {
|
||||
return ty.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
t
|
||||
}
|
||||
|
||||
// For a Vec<Box<T>> return Vec<T>.
|
||||
// For a Vec<T> return Vec<T>.
|
||||
// For a Box<T> return T.
|
||||
fn unbox_vec(t: syn::Type) -> syn::Type {
|
||||
match t {
|
||||
syn::Type::Path(syn::TypePath { ref path, .. }) => {
|
||||
let path = &path.segments;
|
||||
if path.len() == 1 {
|
||||
let seg = &path[0];
|
||||
if seg.ident == "Vec" {
|
||||
if let syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { args, .. }) =
|
||||
&seg.arguments
|
||||
{
|
||||
if args.len() == 1 {
|
||||
let mut args = args.iter();
|
||||
let ok = args.next().unwrap();
|
||||
if let syn::GenericArgument::Type(ty) = ok {
|
||||
let unboxed = unbox(ty.clone());
|
||||
// Wrap it back in a vec.
|
||||
let wrapped = syn::Type::Path(syn::TypePath {
|
||||
qself: None,
|
||||
path: syn::Path {
|
||||
leading_colon: None,
|
||||
segments: {
|
||||
let mut segments = syn::punctuated::Punctuated::new();
|
||||
segments.push_value(syn::PathSegment {
|
||||
ident: syn::Ident::new("Vec", proc_macro2::Span::call_site()),
|
||||
arguments: syn::PathArguments::AngleBracketed(
|
||||
syn::AngleBracketedGenericArguments {
|
||||
colon2_token: None,
|
||||
lt_token: syn::token::Lt::default(),
|
||||
args: {
|
||||
let mut args = syn::punctuated::Punctuated::new();
|
||||
args.push_value(syn::GenericArgument::Type(unboxed));
|
||||
args
|
||||
},
|
||||
gt_token: syn::token::Gt::default(),
|
||||
},
|
||||
),
|
||||
});
|
||||
segments
|
||||
},
|
||||
},
|
||||
});
|
||||
return wrapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
t
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@ -672,7 +787,7 @@ mod tests {
|
||||
fn inner_show(
|
||||
/// The args to do shit to.
|
||||
args: Option<f64>
|
||||
) -> Box<f64> {
|
||||
) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
@ -693,7 +808,7 @@ mod tests {
|
||||
fn inner_show(
|
||||
/// The args to do shit to.
|
||||
args: [f64; 2]
|
||||
) -> Box<f64> {
|
||||
) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
@ -714,7 +829,7 @@ mod tests {
|
||||
fn inner_import(
|
||||
/// The args to do shit to.
|
||||
args: Option<kittycad::types::InputFormat>
|
||||
) -> Box<f64> {
|
||||
) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
@ -727,4 +842,52 @@ mod tests {
|
||||
&openapitor::types::get_text_fmt(&item).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdlib_return_vec_sketch_group() {
|
||||
let (item, errors) = do_stdlib(
|
||||
quote! {
|
||||
name = "import",
|
||||
},
|
||||
quote! {
|
||||
fn inner_import(
|
||||
/// The args to do shit to.
|
||||
args: Option<kittycad::types::InputFormat>
|
||||
) -> Result<Vec<SketchGroup>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(errors.is_empty());
|
||||
expectorate::assert_contents(
|
||||
"tests/return_vec_sketch_group.gen",
|
||||
&openapitor::types::get_text_fmt(&item).unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdlib_return_vec_box_sketch_group() {
|
||||
let (item, errors) = do_stdlib(
|
||||
quote! {
|
||||
name = "import",
|
||||
},
|
||||
quote! {
|
||||
fn inner_import(
|
||||
/// The args to do shit to.
|
||||
args: Option<kittycad::types::InputFormat>
|
||||
) -> Result<Vec<Box<SketchGroup>>> {
|
||||
args
|
||||
}
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(errors.is_empty());
|
||||
expectorate::assert_contents(
|
||||
"tests/return_vec_box_sketch_group.gen",
|
||||
&openapitor::types::get_text_fmt(&item).unwrap(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl crate::docs::StdLibFn for Show {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "number".to_string(),
|
||||
schema: f64::json_schema(&mut generator),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
@ -77,6 +77,6 @@ impl crate::docs::StdLibFn for Show {
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_show(#[doc = r" The args to do shit to."] args: [f64; 2]) -> Box<f64> {
|
||||
fn inner_show(#[doc = r" The args to do shit to."] args: [f64; 2]) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl crate::docs::StdLibFn for Show {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "number".to_string(),
|
||||
schema: f64::json_schema(&mut generator),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ impl crate::docs::StdLibFn for LineTo {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "SketchGroup".to_string(),
|
||||
schema: SketchGroup::json_schema(&mut generator),
|
||||
schema: <SketchGroup>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl crate::docs::StdLibFn for Min {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "number".to_string(),
|
||||
schema: f64::json_schema(&mut generator),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl crate::docs::StdLibFn for Show {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "number".to_string(),
|
||||
schema: f64::json_schema(&mut generator),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
@ -77,6 +77,6 @@ impl crate::docs::StdLibFn for Show {
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_show(#[doc = r" The args to do shit to."] args: Option<f64>) -> Box<f64> {
|
||||
fn inner_show(#[doc = r" The args to do shit to."] args: Option<f64>) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ impl crate::docs::StdLibFn for Import {
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "number".to_string(),
|
||||
schema: f64::json_schema(&mut generator),
|
||||
schema: <f64>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
@ -79,6 +79,6 @@ impl crate::docs::StdLibFn for Import {
|
||||
|
||||
fn inner_import(
|
||||
#[doc = r" The args to do shit to."] args: Option<kittycad::types::InputFormat>,
|
||||
) -> Box<f64> {
|
||||
) -> Result<Box<f64>> {
|
||||
args
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
#[allow(non_camel_case_types, missing_docs)]
|
||||
#[doc = "Std lib function: import"]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
|
||||
#[ts(export)]
|
||||
pub(crate) struct Import {}
|
||||
|
||||
#[allow(non_upper_case_globals, missing_docs)]
|
||||
#[doc = "Std lib function: import"]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||
>,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
fn name(&self) -> String {
|
||||
"import".to_string()
|
||||
}
|
||||
|
||||
fn summary(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn tags(&self) -> Vec<String> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
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),
|
||||
required: false,
|
||||
}]
|
||||
}
|
||||
|
||||
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "[SketchGroup]".to_string(),
|
||||
schema: <Vec<SketchGroup>>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn unpublished(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deprecated(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||
boxed_import
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_import(
|
||||
#[doc = r" The args to do shit to."] args: Option<kittycad::types::InputFormat>,
|
||||
) -> Result<Vec<Box<SketchGroup>>> {
|
||||
args
|
||||
}
|
84
src/wasm-lib/derive-docs/tests/return_vec_sketch_group.gen
Normal file
84
src/wasm-lib/derive-docs/tests/return_vec_sketch_group.gen
Normal file
@ -0,0 +1,84 @@
|
||||
#[allow(non_camel_case_types, missing_docs)]
|
||||
#[doc = "Std lib function: import"]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
|
||||
#[ts(export)]
|
||||
pub(crate) struct Import {}
|
||||
|
||||
#[allow(non_upper_case_globals, missing_docs)]
|
||||
#[doc = "Std lib function: import"]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
|
||||
>,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
fn name(&self) -> String {
|
||||
"import".to_string()
|
||||
}
|
||||
|
||||
fn summary(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn tags(&self) -> Vec<String> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
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),
|
||||
required: false,
|
||||
}]
|
||||
}
|
||||
|
||||
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "[SketchGroup]".to_string(),
|
||||
schema: <Vec<SketchGroup>>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn unpublished(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deprecated(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||
boxed_import
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_import(
|
||||
#[doc = r" The args to do shit to."] args: Option<kittycad::types::InputFormat>,
|
||||
) -> Result<Vec<SketchGroup>> {
|
||||
args
|
||||
}
|
@ -52,7 +52,12 @@ impl crate::docs::StdLibFn for Show {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
None
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "()".to_string(),
|
||||
schema: <()>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn unpublished(&self) -> bool {
|
||||
|
Reference in New Issue
Block a user