Allow lifetime refs in KCL stdlib parameters
This commit is contained in:
		@ -96,10 +96,16 @@ fn do_stdlib_inner(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if !ast.sig.generics.params.is_empty() {
 | 
			
		||||
        errors.push(Error::new_spanned(
 | 
			
		||||
            &ast.sig.generics,
 | 
			
		||||
            "generics are not permitted for stdlib functions",
 | 
			
		||||
        ));
 | 
			
		||||
        if ast.sig.generics.params.iter().any(|generic_type| match generic_type {
 | 
			
		||||
            syn::GenericParam::Lifetime(_) => false,
 | 
			
		||||
            syn::GenericParam::Type(_) => true,
 | 
			
		||||
            syn::GenericParam::Const(_) => true,
 | 
			
		||||
        }) {
 | 
			
		||||
            errors.push(Error::new_spanned(
 | 
			
		||||
                &ast.sig.generics,
 | 
			
		||||
                "Stdlib functions may not be generic over types or constants, only lifetimes.",
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ast.sig.variadic.is_some() {
 | 
			
		||||
@ -650,7 +656,12 @@ impl Parse for ItemFnForSignature {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn clean_ty_string(t: &str) -> (String, proc_macro2::TokenStream) {
 | 
			
		||||
    let mut ty_string = t.replace('&', "").replace("mut", "").replace(' ', "");
 | 
			
		||||
    let mut ty_string = t
 | 
			
		||||
        .replace("& 'a", "")
 | 
			
		||||
        .replace('&', "")
 | 
			
		||||
        .replace("mut", "")
 | 
			
		||||
        .replace("< 'a >", "")
 | 
			
		||||
        .replace(' ', "");
 | 
			
		||||
    if ty_string.starts_with("Args") {
 | 
			
		||||
        ty_string = "Args".to_string();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,56 @@ fn test_get_inner_array_type() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_args_with_refs() {
 | 
			
		||||
    let (item, mut errors) = do_stdlib(
 | 
			
		||||
        quote! {
 | 
			
		||||
            name = "someFn",
 | 
			
		||||
        },
 | 
			
		||||
        quote! {
 | 
			
		||||
            /// Docs
 | 
			
		||||
            /// ```
 | 
			
		||||
            /// someFn()
 | 
			
		||||
            /// ```
 | 
			
		||||
            fn someFn(
 | 
			
		||||
                data: &'a str,
 | 
			
		||||
            ) -> i32 {
 | 
			
		||||
                3
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    .unwrap();
 | 
			
		||||
    if let Some(e) = errors.pop() {
 | 
			
		||||
        panic!("{e}");
 | 
			
		||||
    }
 | 
			
		||||
    expectorate::assert_contents("tests/args_with_refs.gen", &get_text_fmt(&item).unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_args_with_lifetime() {
 | 
			
		||||
    let (item, mut errors) = do_stdlib(
 | 
			
		||||
        quote! {
 | 
			
		||||
            name = "someFn",
 | 
			
		||||
        },
 | 
			
		||||
        quote! {
 | 
			
		||||
            /// Docs
 | 
			
		||||
            /// ```
 | 
			
		||||
            /// someFn()
 | 
			
		||||
            /// ```
 | 
			
		||||
            fn someFn<'a>(
 | 
			
		||||
                data: Foo<'a>,
 | 
			
		||||
            ) -> i32 {
 | 
			
		||||
                3
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    .unwrap();
 | 
			
		||||
    if let Some(e) = errors.pop() {
 | 
			
		||||
        panic!("{e}");
 | 
			
		||||
    }
 | 
			
		||||
    expectorate::assert_contents("tests/args_with_lifetime.gen", &get_text_fmt(&item).unwrap());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn test_stdlib_line_to() {
 | 
			
		||||
    let (item, errors) = do_stdlib(
 | 
			
		||||
@ -64,7 +114,6 @@ fn test_stdlib_line_to() {
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    .unwrap();
 | 
			
		||||
    let _expected = quote! {};
 | 
			
		||||
 | 
			
		||||
    assert!(errors.is_empty());
 | 
			
		||||
    expectorate::assert_contents("tests/lineTo.gen", &get_text_fmt(&item).unwrap());
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										194
									
								
								src/wasm-lib/derive-docs/tests/args_with_lifetime.gen
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/wasm-lib/derive-docs/tests/args_with_lifetime.gen
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,194 @@
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test_examples_someFn {
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_mock_example_someFn0() {
 | 
			
		||||
        let tokens = crate::token::lexer("someFn()").unwrap();
 | 
			
		||||
        let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
        let program = parser.ast().unwrap();
 | 
			
		||||
        let ctx = crate::executor::ExecutorContext {
 | 
			
		||||
            engine: std::sync::Arc::new(Box::new(
 | 
			
		||||
                crate::engine::conn_mock::EngineConnection::new()
 | 
			
		||||
                    .await
 | 
			
		||||
                    .unwrap(),
 | 
			
		||||
            )),
 | 
			
		||||
            fs: std::sync::Arc::new(crate::fs::FileManager::new()),
 | 
			
		||||
            stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
 | 
			
		||||
            settings: Default::default(),
 | 
			
		||||
            is_mock: true,
 | 
			
		||||
        };
 | 
			
		||||
        ctx.run(program, None).await.unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
 | 
			
		||||
    async fn serial_test_example_someFn0() {
 | 
			
		||||
        let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
 | 
			
		||||
        let http_client = reqwest::Client::builder()
 | 
			
		||||
            .user_agent(user_agent)
 | 
			
		||||
            .timeout(std::time::Duration::from_secs(600))
 | 
			
		||||
            .connect_timeout(std::time::Duration::from_secs(60));
 | 
			
		||||
        let ws_client = reqwest::Client::builder()
 | 
			
		||||
            .user_agent(user_agent)
 | 
			
		||||
            .timeout(std::time::Duration::from_secs(600))
 | 
			
		||||
            .connect_timeout(std::time::Duration::from_secs(60))
 | 
			
		||||
            .connection_verbose(true)
 | 
			
		||||
            .tcp_keepalive(std::time::Duration::from_secs(600))
 | 
			
		||||
            .http1_only();
 | 
			
		||||
        let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
 | 
			
		||||
        let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
 | 
			
		||||
        if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
 | 
			
		||||
            client.set_base_url(addr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let tokens = crate::token::lexer("someFn()").unwrap();
 | 
			
		||||
        let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
        let program = parser.ast().unwrap();
 | 
			
		||||
        let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        ctx.run(program, None).await.unwrap();
 | 
			
		||||
        ctx.engine
 | 
			
		||||
            .send_modeling_cmd(
 | 
			
		||||
                uuid::Uuid::new_v4(),
 | 
			
		||||
                crate::executor::SourceRange::default(),
 | 
			
		||||
                kittycad::types::ModelingCmd::ZoomToFit {
 | 
			
		||||
                    object_ids: Default::default(),
 | 
			
		||||
                    padding: 0.1,
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let resp = ctx
 | 
			
		||||
            .engine
 | 
			
		||||
            .send_modeling_cmd(
 | 
			
		||||
                uuid::Uuid::new_v4(),
 | 
			
		||||
                crate::executor::SourceRange::default(),
 | 
			
		||||
                kittycad::types::ModelingCmd::TakeSnapshot {
 | 
			
		||||
                    format: kittycad::types::ImageFormat::Png,
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let output_file =
 | 
			
		||||
            std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
 | 
			
		||||
        if let kittycad::types::OkWebSocketResponseData::Modeling {
 | 
			
		||||
            modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
 | 
			
		||||
        } = &resp
 | 
			
		||||
        {
 | 
			
		||||
            std::fs::write(&output_file, &data.contents.0).unwrap();
 | 
			
		||||
        } else {
 | 
			
		||||
            panic!("Unexpected response from engine: {:?}", resp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let actual = image::io::Reader::open(output_file)
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .decode()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        twenty_twenty::assert_image(
 | 
			
		||||
            &format!("tests/outputs/{}.png", "serial_test_example_someFn0"),
 | 
			
		||||
            &actual,
 | 
			
		||||
            1.0,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(non_camel_case_types, missing_docs)]
 | 
			
		||||
#[doc = "Std lib function: someFn\nDocs"]
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
pub(crate) struct SomeFn {}
 | 
			
		||||
 | 
			
		||||
#[allow(non_upper_case_globals, missing_docs)]
 | 
			
		||||
#[doc = "Std lib function: someFn\nDocs"]
 | 
			
		||||
pub(crate) const SomeFn: SomeFn = SomeFn {};
 | 
			
		||||
fn boxed_someFn(
 | 
			
		||||
    args: crate::std::Args,
 | 
			
		||||
) -> std::pin::Pin<
 | 
			
		||||
    Box<
 | 
			
		||||
        dyn std::future::Future<
 | 
			
		||||
                Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
 | 
			
		||||
            > + Send,
 | 
			
		||||
    >,
 | 
			
		||||
> {
 | 
			
		||||
    Box::pin(someFn(args))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl crate::docs::StdLibFn for SomeFn {
 | 
			
		||||
    fn name(&self) -> String {
 | 
			
		||||
        "someFn".to_string()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn summary(&self) -> String {
 | 
			
		||||
        "Docs".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: "data".to_string(),
 | 
			
		||||
            type_: "Foo".to_string(),
 | 
			
		||||
            schema: Foo::json_schema(&mut generator),
 | 
			
		||||
            required: true,
 | 
			
		||||
        }]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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_: "i32".to_string(),
 | 
			
		||||
            schema: <i32>::json_schema(&mut generator),
 | 
			
		||||
            required: true,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn unpublished(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn deprecated(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn examples(&self) -> Vec<String> {
 | 
			
		||||
        let code_blocks = vec!["someFn()"];
 | 
			
		||||
        code_blocks
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|cb| {
 | 
			
		||||
                let tokens = crate::token::lexer(cb).unwrap();
 | 
			
		||||
                let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
                let program = parser.ast().unwrap();
 | 
			
		||||
                let mut options: crate::ast::types::FormatOptions = Default::default();
 | 
			
		||||
                options.insert_final_newline = false;
 | 
			
		||||
                program.recast(&options, 0)
 | 
			
		||||
            })
 | 
			
		||||
            .collect::<Vec<String>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn std_lib_fn(&self) -> crate::std::StdFn {
 | 
			
		||||
        boxed_someFn
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
 | 
			
		||||
        Box::new(self.clone())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[doc = r" Docs"]
 | 
			
		||||
#[doc = r" ```"]
 | 
			
		||||
#[doc = r" someFn()"]
 | 
			
		||||
#[doc = r" ```"]
 | 
			
		||||
fn someFn<'a>(data: Foo<'a>) -> i32 {
 | 
			
		||||
    3
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										194
									
								
								src/wasm-lib/derive-docs/tests/args_with_refs.gen
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								src/wasm-lib/derive-docs/tests/args_with_refs.gen
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,194 @@
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod test_examples_someFn {
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread")]
 | 
			
		||||
    async fn test_mock_example_someFn0() {
 | 
			
		||||
        let tokens = crate::token::lexer("someFn()").unwrap();
 | 
			
		||||
        let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
        let program = parser.ast().unwrap();
 | 
			
		||||
        let ctx = crate::executor::ExecutorContext {
 | 
			
		||||
            engine: std::sync::Arc::new(Box::new(
 | 
			
		||||
                crate::engine::conn_mock::EngineConnection::new()
 | 
			
		||||
                    .await
 | 
			
		||||
                    .unwrap(),
 | 
			
		||||
            )),
 | 
			
		||||
            fs: std::sync::Arc::new(crate::fs::FileManager::new()),
 | 
			
		||||
            stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
 | 
			
		||||
            settings: Default::default(),
 | 
			
		||||
            is_mock: true,
 | 
			
		||||
        };
 | 
			
		||||
        ctx.run(program, None).await.unwrap();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[tokio::test(flavor = "multi_thread", worker_threads = 5)]
 | 
			
		||||
    async fn serial_test_example_someFn0() {
 | 
			
		||||
        let user_agent = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
 | 
			
		||||
        let http_client = reqwest::Client::builder()
 | 
			
		||||
            .user_agent(user_agent)
 | 
			
		||||
            .timeout(std::time::Duration::from_secs(600))
 | 
			
		||||
            .connect_timeout(std::time::Duration::from_secs(60));
 | 
			
		||||
        let ws_client = reqwest::Client::builder()
 | 
			
		||||
            .user_agent(user_agent)
 | 
			
		||||
            .timeout(std::time::Duration::from_secs(600))
 | 
			
		||||
            .connect_timeout(std::time::Duration::from_secs(60))
 | 
			
		||||
            .connection_verbose(true)
 | 
			
		||||
            .tcp_keepalive(std::time::Duration::from_secs(600))
 | 
			
		||||
            .http1_only();
 | 
			
		||||
        let token = std::env::var("KITTYCAD_API_TOKEN").expect("KITTYCAD_API_TOKEN not set");
 | 
			
		||||
        let mut client = kittycad::Client::new_from_reqwest(token, http_client, ws_client);
 | 
			
		||||
        if let Ok(addr) = std::env::var("LOCAL_ENGINE_ADDR") {
 | 
			
		||||
            client.set_base_url(addr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let tokens = crate::token::lexer("someFn()").unwrap();
 | 
			
		||||
        let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
        let program = parser.ast().unwrap();
 | 
			
		||||
        let ctx = crate::executor::ExecutorContext::new(&client, Default::default())
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        ctx.run(program, None).await.unwrap();
 | 
			
		||||
        ctx.engine
 | 
			
		||||
            .send_modeling_cmd(
 | 
			
		||||
                uuid::Uuid::new_v4(),
 | 
			
		||||
                crate::executor::SourceRange::default(),
 | 
			
		||||
                kittycad::types::ModelingCmd::ZoomToFit {
 | 
			
		||||
                    object_ids: Default::default(),
 | 
			
		||||
                    padding: 0.1,
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let resp = ctx
 | 
			
		||||
            .engine
 | 
			
		||||
            .send_modeling_cmd(
 | 
			
		||||
                uuid::Uuid::new_v4(),
 | 
			
		||||
                crate::executor::SourceRange::default(),
 | 
			
		||||
                kittycad::types::ModelingCmd::TakeSnapshot {
 | 
			
		||||
                    format: kittycad::types::ImageFormat::Png,
 | 
			
		||||
                },
 | 
			
		||||
            )
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        let output_file =
 | 
			
		||||
            std::env::temp_dir().join(format!("kcl_output_{}.png", uuid::Uuid::new_v4()));
 | 
			
		||||
        if let kittycad::types::OkWebSocketResponseData::Modeling {
 | 
			
		||||
            modeling_response: kittycad::types::OkModelingCmdResponse::TakeSnapshot { data },
 | 
			
		||||
        } = &resp
 | 
			
		||||
        {
 | 
			
		||||
            std::fs::write(&output_file, &data.contents.0).unwrap();
 | 
			
		||||
        } else {
 | 
			
		||||
            panic!("Unexpected response from engine: {:?}", resp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let actual = image::io::Reader::open(output_file)
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .decode()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        twenty_twenty::assert_image(
 | 
			
		||||
            &format!("tests/outputs/{}.png", "serial_test_example_someFn0"),
 | 
			
		||||
            &actual,
 | 
			
		||||
            1.0,
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[allow(non_camel_case_types, missing_docs)]
 | 
			
		||||
#[doc = "Std lib function: someFn\nDocs"]
 | 
			
		||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
 | 
			
		||||
#[ts(export)]
 | 
			
		||||
pub(crate) struct SomeFn {}
 | 
			
		||||
 | 
			
		||||
#[allow(non_upper_case_globals, missing_docs)]
 | 
			
		||||
#[doc = "Std lib function: someFn\nDocs"]
 | 
			
		||||
pub(crate) const SomeFn: SomeFn = SomeFn {};
 | 
			
		||||
fn boxed_someFn(
 | 
			
		||||
    args: crate::std::Args,
 | 
			
		||||
) -> std::pin::Pin<
 | 
			
		||||
    Box<
 | 
			
		||||
        dyn std::future::Future<
 | 
			
		||||
                Output = anyhow::Result<crate::executor::MemoryItem, crate::errors::KclError>,
 | 
			
		||||
            > + Send,
 | 
			
		||||
    >,
 | 
			
		||||
> {
 | 
			
		||||
    Box::pin(someFn(args))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl crate::docs::StdLibFn for SomeFn {
 | 
			
		||||
    fn name(&self) -> String {
 | 
			
		||||
        "someFn".to_string()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn summary(&self) -> String {
 | 
			
		||||
        "Docs".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: "data".to_string(),
 | 
			
		||||
            type_: "string".to_string(),
 | 
			
		||||
            schema: str::json_schema(&mut generator),
 | 
			
		||||
            required: true,
 | 
			
		||||
        }]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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_: "i32".to_string(),
 | 
			
		||||
            schema: <i32>::json_schema(&mut generator),
 | 
			
		||||
            required: true,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn unpublished(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn deprecated(&self) -> bool {
 | 
			
		||||
        false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn examples(&self) -> Vec<String> {
 | 
			
		||||
        let code_blocks = vec!["someFn()"];
 | 
			
		||||
        code_blocks
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|cb| {
 | 
			
		||||
                let tokens = crate::token::lexer(cb).unwrap();
 | 
			
		||||
                let parser = crate::parser::Parser::new(tokens);
 | 
			
		||||
                let program = parser.ast().unwrap();
 | 
			
		||||
                let mut options: crate::ast::types::FormatOptions = Default::default();
 | 
			
		||||
                options.insert_final_newline = false;
 | 
			
		||||
                program.recast(&options, 0)
 | 
			
		||||
            })
 | 
			
		||||
            .collect::<Vec<String>>()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn std_lib_fn(&self) -> crate::std::StdFn {
 | 
			
		||||
        boxed_someFn
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
 | 
			
		||||
        Box::new(self.clone())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[doc = r" Docs"]
 | 
			
		||||
#[doc = r" ```"]
 | 
			
		||||
#[doc = r" someFn()"]
 | 
			
		||||
#[doc = r" ```"]
 | 
			
		||||
fn someFn(data: &'a str) -> i32 {
 | 
			
		||||
    3
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user