File diff suppressed because one or more lines are too long
@ -21,8 +21,8 @@ rem(num: i64, divisor: i64) -> i64
|
|||||||
|
|
||||||
| Name | Type | Description | Required |
|
| Name | Type | Description | Required |
|
||||||
|----------|------|-------------|----------|
|
|----------|------|-------------|----------|
|
||||||
| `num` | `i64` | | Yes |
|
| `num` | `i64` | The number which will be divided by `divisor`. | Yes |
|
||||||
| `divisor` | `i64` | | Yes |
|
| `divisor` | `i64` | The number which will divide `num`. | Yes |
|
||||||
|
|
||||||
### Returns
|
### Returns
|
||||||
|
|
||||||
|
3996
docs/kcl/std.json
3996
docs/kcl/std.json
File diff suppressed because it is too large
Load Diff
54
src/wasm-lib/Cargo.lock
generated
54
src/wasm-lib/Cargo.lock
generated
@ -121,9 +121,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.93"
|
version = "1.0.94"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
|
checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
]
|
]
|
||||||
@ -401,9 +401,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.38"
|
version = "0.4.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android-tzdata",
|
"android-tzdata",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
@ -1112,7 +1112,7 @@ dependencies = [
|
|||||||
"fnv",
|
"fnv",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"indexmap 2.7.0",
|
"indexmap 2.7.0",
|
||||||
"slab",
|
"slab",
|
||||||
"tokio",
|
"tokio",
|
||||||
@ -1215,9 +1215,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "1.1.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
@ -1242,7 +1242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1253,7 +1253,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
@ -1303,7 +1303,7 @@ dependencies = [
|
|||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"httparse",
|
"httparse",
|
||||||
"itoa",
|
"itoa",
|
||||||
@ -1320,7 +1320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"rustls",
|
"rustls",
|
||||||
@ -1340,7 +1340,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@ -1706,7 +1706,7 @@ dependencies = [
|
|||||||
"git_rev",
|
"git_rev",
|
||||||
"gltf-json",
|
"gltf-json",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"iai",
|
"iai",
|
||||||
"image",
|
"image",
|
||||||
"indexmap 2.7.0",
|
"indexmap 2.7.0",
|
||||||
@ -1793,7 +1793,7 @@ dependencies = [
|
|||||||
"data-encoding",
|
"data-encoding",
|
||||||
"format_serde_error",
|
"format_serde_error",
|
||||||
"futures",
|
"futures",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"itertools 0.13.0",
|
"itertools 0.13.0",
|
||||||
"log",
|
"log",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
@ -1819,9 +1819,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kittycad-modeling-cmds"
|
name = "kittycad-modeling-cmds"
|
||||||
version = "0.2.77"
|
version = "0.2.79"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b77259b37acafa360d98af27431ac394bc8899eeed7037513832ddbee856811"
|
checksum = "10a9cab4476455be70ea57643c31444068b056d091bd348cab6044c0d8ad7fcc"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1829,7 +1829,7 @@ dependencies = [
|
|||||||
"enum-iterator",
|
"enum-iterator",
|
||||||
"enum-iterator-derive",
|
"enum-iterator-derive",
|
||||||
"euler",
|
"euler",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"kittycad-modeling-cmds-macros",
|
"kittycad-modeling-cmds-macros",
|
||||||
"kittycad-unit-conversion-derive",
|
"kittycad-unit-conversion-derive",
|
||||||
"measurements",
|
"measurements",
|
||||||
@ -2863,7 +2863,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2",
|
"h2",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"http-body 1.0.1",
|
"http-body 1.0.1",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
@ -2905,7 +2905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "f67ad7fdf5c0a015763fcd164bee294b13fb7b6f89f1b55961d40f00c3e32d6b"
|
checksum = "f67ad7fdf5c0a015763fcd164bee294b13fb7b6f89f1b55961d40f00c3e32d6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
]
|
]
|
||||||
@ -2918,7 +2918,7 @@ checksum = "d1ccd3b55e711f91a9885a2fa6fbbb2e39db1776420b062efc058c6410f7e5e3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 1.0.68",
|
"thiserror 1.0.68",
|
||||||
@ -2935,7 +2935,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"hyper 1.4.1",
|
"hyper 1.4.1",
|
||||||
"parking_lot 0.11.2",
|
"parking_lot 0.11.2",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
@ -2956,7 +2956,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"matchit",
|
"matchit",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
@ -3200,9 +3200,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.215"
|
version = "1.0.216"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
@ -3218,9 +3218,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.215"
|
version = "1.0.216"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -4028,7 +4028,7 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"data-encoding",
|
"data-encoding",
|
||||||
"http 1.1.0",
|
"http 1.2.0",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
@ -76,7 +76,7 @@ members = [
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
http = "1"
|
http = "1"
|
||||||
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
|
kittycad = { version = "0.3.28", default-features = false, features = ["js", "requests"] }
|
||||||
kittycad-modeling-cmds = { version = "0.2.77", features = ["websocket"] }
|
kittycad-modeling-cmds = { version = "0.2.79", features = ["websocket"] }
|
||||||
|
|
||||||
[workspace.lints.clippy]
|
[workspace.lints.clippy]
|
||||||
assertions_on_result_states = "warn"
|
assertions_on_result_states = "warn"
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
mod tests;
|
mod tests;
|
||||||
mod unbox;
|
mod unbox;
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use convert_case::Casing;
|
use convert_case::Casing;
|
||||||
use inflector::Inflector;
|
use inflector::Inflector;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
@ -47,6 +49,10 @@ struct StdlibMetadata {
|
|||||||
/// If false, all arguments require labels.
|
/// If false, all arguments require labels.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
unlabeled_first: bool,
|
unlabeled_first: bool,
|
||||||
|
|
||||||
|
/// Key = argument name, value = argument doc.
|
||||||
|
#[serde(default)]
|
||||||
|
arg_docs: HashMap<String, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
@ -282,6 +288,17 @@ fn do_stdlib_inner(
|
|||||||
|
|
||||||
let ty_string = rust_type_to_openapi_type(&ty_string);
|
let ty_string = rust_type_to_openapi_type(&ty_string);
|
||||||
let required = !ty_ident.to_string().starts_with("Option <");
|
let required = !ty_ident.to_string().starts_with("Option <");
|
||||||
|
let description = if let Some(s) = metadata.arg_docs.get(&arg_name) {
|
||||||
|
quote! { #s }
|
||||||
|
} else if metadata.keywords && ty_string != "Args" && ty_string != "ExecState" {
|
||||||
|
errors.push(Error::new_spanned(
|
||||||
|
&arg,
|
||||||
|
"Argument was not documented in the arg_docs block",
|
||||||
|
));
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
quote! { String::new() }
|
||||||
|
};
|
||||||
let label_required = !(i == 0 && metadata.unlabeled_first);
|
let label_required = !(i == 0 && metadata.unlabeled_first);
|
||||||
if ty_string != "ExecState" && ty_string != "Args" {
|
if ty_string != "ExecState" && ty_string != "Args" {
|
||||||
let schema = quote! {
|
let schema = quote! {
|
||||||
@ -294,6 +311,7 @@ fn do_stdlib_inner(
|
|||||||
schema: #schema,
|
schema: #schema,
|
||||||
required: #required,
|
required: #required,
|
||||||
label_required: #label_required,
|
label_required: #label_required,
|
||||||
|
description: #description.to_string(),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -355,6 +373,7 @@ fn do_stdlib_inner(
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,6 +116,9 @@ fn test_stdlib_line_to() {
|
|||||||
let (item, errors) = do_stdlib(
|
let (item, errors) = do_stdlib(
|
||||||
quote! {
|
quote! {
|
||||||
name = "lineTo",
|
name = "lineTo",
|
||||||
|
arg_docs = {
|
||||||
|
sketch = "the sketch you're adding the line to"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
quote! {
|
quote! {
|
||||||
/// This is some function.
|
/// This is some function.
|
||||||
|
@ -91,6 +91,7 @@ impl crate::docs::StdLibFn for SomeFn {
|
|||||||
schema: generator.root_schema_for::<Foo>(),
|
schema: generator.root_schema_for::<Foo>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +106,7 @@ impl crate::docs::StdLibFn for SomeFn {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ impl crate::docs::StdLibFn for SomeFn {
|
|||||||
schema: generator.root_schema_for::<str>(),
|
schema: generator.root_schema_for::<str>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,6 +106,7 @@ impl crate::docs::StdLibFn for SomeFn {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema: generator.root_schema_for::<[f64; 2usize]>(),
|
schema: generator.root_schema_for::<[f64; 2usize]>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +144,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema: generator.root_schema_for::<f64>(),
|
schema: generator.root_schema_for::<f64>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ impl crate::docs::StdLibFn for MyFunc {
|
|||||||
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
||||||
required: false,
|
required: false,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +145,7 @@ impl crate::docs::StdLibFn for MyFunc {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@ impl crate::docs::StdLibFn for LineTo {
|
|||||||
schema: generator.root_schema_for::<LineToData>(),
|
schema: generator.root_schema_for::<LineToData>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
},
|
},
|
||||||
crate::docs::StdLibFnArg {
|
crate::docs::StdLibFnArg {
|
||||||
name: "sketch".to_string(),
|
name: "sketch".to_string(),
|
||||||
@ -138,6 +139,7 @@ impl crate::docs::StdLibFn for LineTo {
|
|||||||
schema: generator.root_schema_for::<Sketch>(),
|
schema: generator.root_schema_for::<Sketch>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: "the sketch you're adding the line to".to_string(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -153,6 +155,7 @@ impl crate::docs::StdLibFn for LineTo {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ impl crate::docs::StdLibFn for Min {
|
|||||||
schema: generator.root_schema_for::<Vec<f64>>(),
|
schema: generator.root_schema_for::<Vec<f64>>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +144,7 @@ impl crate::docs::StdLibFn for Min {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema: generator.root_schema_for::<Option<f64>>(),
|
schema: generator.root_schema_for::<Option<f64>>(),
|
||||||
required: false,
|
required: false,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
||||||
required: false,
|
required: false,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
||||||
required: false,
|
required: false,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
schema: generator.root_schema_for::<Option<kittycad::types::InputFormat>>(),
|
||||||
required: false,
|
required: false,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Import {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema: generator.root_schema_for::<Vec<f64>>(),
|
schema: generator.root_schema_for::<Vec<f64>>(),
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new().to_string(),
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +107,7 @@ impl crate::docs::StdLibFn for Show {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ impl crate::docs::StdLibFn for SomeFunction {
|
|||||||
schema,
|
schema,
|
||||||
required: true,
|
required: true,
|
||||||
label_required: true,
|
label_required: true,
|
||||||
|
description: String::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,11 @@ impl EngineConnection {
|
|||||||
uuid_to_cpp(path_id)
|
uuid_to_cpp(path_id)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
kcmc::ModelingCmd::Extrude(kcmc::Extrude { distance, target }) => {
|
kcmc::ModelingCmd::Extrude(kcmc::Extrude {
|
||||||
|
distance,
|
||||||
|
target,
|
||||||
|
faces: _, // Engine team: start using this once the frontend and engine both use it.
|
||||||
|
}) => {
|
||||||
format!(
|
format!(
|
||||||
r#"
|
r#"
|
||||||
scene->getSceneObject(Utils::UUID("{target}"))->extrudeToSolid3D({} * scaleFactor, true);
|
scene->getSceneObject(Utils::UUID("{target}"))->extrudeToSolid3D({} * scaleFactor, true);
|
||||||
|
@ -59,6 +59,12 @@ pub struct StdLibFnArg {
|
|||||||
pub schema: schemars::schema::RootSchema,
|
pub schema: schemars::schema::RootSchema,
|
||||||
/// If the argument is required.
|
/// If the argument is required.
|
||||||
pub required: bool,
|
pub required: bool,
|
||||||
|
/// Additional information that could be used instead of the type's description.
|
||||||
|
/// This is helpful if the type is really basic, like "u32" -- that won't tell the user much about
|
||||||
|
/// how this argument is meant to be used.
|
||||||
|
/// Empty string means this has no docs.
|
||||||
|
#[serde(default, skip_serializing_if = "String::is_empty")]
|
||||||
|
pub description: String,
|
||||||
/// Even in functions that use keyword arguments, not every parameter requires a label (most do though).
|
/// Even in functions that use keyword arguments, not every parameter requires a label (most do though).
|
||||||
/// Some functions allow one unlabeled parameter, which has to be first in the
|
/// Some functions allow one unlabeled parameter, which has to be first in the
|
||||||
/// argument list.
|
/// argument list.
|
||||||
@ -106,6 +112,11 @@ impl StdLibFnArg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn description(&self) -> Option<String> {
|
pub fn description(&self) -> Option<String> {
|
||||||
|
// Check if we explicitly gave this stdlib arg a description.
|
||||||
|
if !self.description.is_empty() {
|
||||||
|
return Some(self.description.clone());
|
||||||
|
}
|
||||||
|
// If not, then try to get something meaningful from the schema.
|
||||||
get_description_string_from_schema(&self.schema.clone())
|
get_description_string_from_schema(&self.schema.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2539,6 +2539,7 @@ fn fn_call_kw(i: &mut TokenSlice) -> PResult<Node<CallExpressionKw>> {
|
|||||||
let initial_unlabeled_arg = opt((expression, comma, opt(whitespace)).map(|(arg, _, _)| arg)).parse_next(i)?;
|
let initial_unlabeled_arg = opt((expression, comma, opt(whitespace)).map(|(arg, _, _)| arg)).parse_next(i)?;
|
||||||
let args = labeled_arguments(i)?;
|
let args = labeled_arguments(i)?;
|
||||||
ignore_whitespace(i);
|
ignore_whitespace(i);
|
||||||
|
opt(comma_sep).parse_next(i)?;
|
||||||
let end = close_paren.parse_next(i)?.end;
|
let end = close_paren.parse_next(i)?.end;
|
||||||
|
|
||||||
Ok(Node {
|
Ok(Node {
|
||||||
|
@ -133,12 +133,16 @@ impl Args {
|
|||||||
where
|
where
|
||||||
T: FromKclValue<'a>,
|
T: FromKclValue<'a>,
|
||||||
{
|
{
|
||||||
let Some(ref arg) = self.kw_args.unlabeled else {
|
let arg = self
|
||||||
return Err(KclError::Semantic(KclErrorDetails {
|
.kw_args
|
||||||
|
.unlabeled
|
||||||
|
.as_ref()
|
||||||
|
.or(self.args.first())
|
||||||
|
.ok_or(KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: vec![self.source_range],
|
source_ranges: vec![self.source_range],
|
||||||
message: format!("This function requires a value for the special unlabeled first parameter, '{label}'"),
|
message: format!("This function requires a value for the special unlabeled first parameter, '{label}'"),
|
||||||
}));
|
}))?;
|
||||||
};
|
|
||||||
T::from_kcl_val(&arg.value).ok_or_else(|| {
|
T::from_kcl_val(&arg.value).ok_or_else(|| {
|
||||||
KclError::Semantic(KclErrorDetails {
|
KclError::Semantic(KclErrorDetails {
|
||||||
source_ranges: arg.source_ranges(),
|
source_ranges: arg.source_ranges(),
|
||||||
@ -411,13 +415,6 @@ impl Args {
|
|||||||
FromArgs::from_args(self, 0)
|
FromArgs::from_args(self, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_sketches_and_data<'a, T>(&'a self) -> Result<(Vec<Sketch>, Option<T>), KclError>
|
|
||||||
where
|
|
||||||
T: FromArgs<'a> + serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
|
||||||
{
|
|
||||||
FromArgs::from_args(self, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn get_data_and_optional_tag<'a, T>(&'a self) -> Result<(T, Option<FaceTag>), KclError>
|
pub(crate) fn get_data_and_optional_tag<'a, T>(&'a self) -> Result<(T, Option<FaceTag>), KclError>
|
||||||
where
|
where
|
||||||
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
T: serde::de::DeserializeOwned + FromKclValue<'a> + Sized,
|
||||||
@ -865,22 +862,6 @@ impl<'a> FromKclValue<'a> for crate::std::polar::PolarCoordsData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for crate::std::loft::LoftData {
|
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
|
||||||
let obj = arg.as_object()?;
|
|
||||||
let_field_of!(obj, v_degree?);
|
|
||||||
let_field_of!(obj, bez_approximate_rational?);
|
|
||||||
let_field_of!(obj, base_curve_index?);
|
|
||||||
let_field_of!(obj, tolerance?);
|
|
||||||
Some(Self {
|
|
||||||
v_degree,
|
|
||||||
bez_approximate_rational,
|
|
||||||
base_curve_index,
|
|
||||||
tolerance,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> FromKclValue<'a> for crate::std::planes::StandardPlane {
|
impl<'a> FromKclValue<'a> for crate::std::planes::StandardPlane {
|
||||||
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
fn from_kcl_val(arg: &'a KclValue) -> Option<Self> {
|
||||||
let s = arg.as_str()?;
|
let s = arg.as_str()?;
|
||||||
|
@ -113,6 +113,7 @@ async fn inner_extrude(
|
|||||||
ModelingCmd::from(mcmd::Extrude {
|
ModelingCmd::from(mcmd::Extrude {
|
||||||
target: sketch.id.into(),
|
target: sketch.id.into(),
|
||||||
distance: LengthUnit(length),
|
distance: LengthUnit(length),
|
||||||
|
faces: Default::default(),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//! Standard library lofts.
|
//! Standard library lofts.
|
||||||
|
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, ModelingCmd};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds as kcmc;
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
@ -15,45 +15,31 @@ use crate::{
|
|||||||
|
|
||||||
const DEFAULT_V_DEGREE: u32 = 2;
|
const DEFAULT_V_DEGREE: u32 = 2;
|
||||||
|
|
||||||
/// Data for a loft.
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
|
||||||
#[ts(export)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct LoftData {
|
|
||||||
/// Degree of the interpolation. Must be greater than zero.
|
|
||||||
/// For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction.
|
|
||||||
/// This defaults to 2, if not specified.
|
|
||||||
pub v_degree: Option<std::num::NonZeroU32>,
|
|
||||||
/// Attempt to approximate rational curves (such as arcs) using a bezier.
|
|
||||||
/// This will remove banding around interpolations between arcs and non-arcs. It may produce errors in other scenarios
|
|
||||||
/// Over time, this field won't be necessary.
|
|
||||||
#[serde(default)]
|
|
||||||
pub bez_approximate_rational: Option<bool>,
|
|
||||||
/// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
|
|
||||||
#[serde(default)]
|
|
||||||
pub base_curve_index: Option<u32>,
|
|
||||||
/// Tolerance for the loft operation.
|
|
||||||
#[serde(default)]
|
|
||||||
pub tolerance: Option<f64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for LoftData {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
// This unwrap is safe because the default value is always greater than zero.
|
|
||||||
v_degree: Some(std::num::NonZeroU32::new(DEFAULT_V_DEGREE).unwrap()),
|
|
||||||
bez_approximate_rational: None,
|
|
||||||
base_curve_index: None,
|
|
||||||
tolerance: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a 3D surface or solid by interpolating between two or more sketches.
|
/// Create a 3D surface or solid by interpolating between two or more sketches.
|
||||||
pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, KclError> {
|
||||||
let (sketches, data): (Vec<Sketch>, Option<LoftData>) = args.get_sketches_and_data()?;
|
let sketches = args.get_unlabeled_kw_arg("sketches")?;
|
||||||
|
let v_degree: NonZeroU32 = args
|
||||||
|
.get_kw_arg_opt("vDegree")
|
||||||
|
.unwrap_or(NonZeroU32::new(DEFAULT_V_DEGREE).unwrap());
|
||||||
|
// Attempt to approximate rational curves (such as arcs) using a bezier.
|
||||||
|
// This will remove banding around interpolations between arcs and non-arcs. It may produce errors in other scenarios
|
||||||
|
// Over time, this field won't be necessary.
|
||||||
|
let bez_approximate_rational = args.get_kw_arg_opt("bezApproximateRational").unwrap_or(false);
|
||||||
|
// This can be set to override the automatically determined topological base curve, which is usually the first section encountered.
|
||||||
|
let base_curve_index: Option<u32> = args.get_kw_arg_opt("baseCurveIndex");
|
||||||
|
// Tolerance for the loft operation.
|
||||||
|
let tolerance: Option<f64> = args.get_kw_arg_opt("tolerance");
|
||||||
|
|
||||||
let solid = inner_loft(sketches, data, exec_state, args).await?;
|
let solid = inner_loft(
|
||||||
|
sketches,
|
||||||
|
v_degree,
|
||||||
|
bez_approximate_rational,
|
||||||
|
base_curve_index,
|
||||||
|
tolerance,
|
||||||
|
exec_state,
|
||||||
|
args,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
Ok(KclValue::Solid(solid))
|
Ok(KclValue::Solid(solid))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,28 +102,31 @@ pub async fn loft(exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
/// circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
/// circleSketch1 = startSketchOn(offsetPlane('XY', 150))
|
||||||
/// |> circle({ center = [0, 100], radius = 20 }, %)
|
/// |> circle({ center = [0, 100], radius = 20 }, %)
|
||||||
///
|
///
|
||||||
/// loft([squareSketch, circleSketch0, circleSketch1], {
|
/// loft([squareSketch, circleSketch0, circleSketch1],
|
||||||
/// // This can be set to override the automatically determined
|
|
||||||
/// // topological base curve, which is usually the first section encountered.
|
|
||||||
/// baseCurveIndex = 0,
|
/// baseCurveIndex = 0,
|
||||||
/// // Attempt to approximate rational curves (such as arcs) using a bezier.
|
|
||||||
/// // This will remove banding around interpolations between arcs and non-arcs.
|
|
||||||
/// // It may produce errors in other scenarios Over time, this field won't be necessary.
|
|
||||||
/// bezApproximateRational = false,
|
/// bezApproximateRational = false,
|
||||||
/// // Tolerance for the loft operation.
|
|
||||||
/// tolerance = 0.000001,
|
/// tolerance = 0.000001,
|
||||||
/// // Degree of the interpolation. Must be greater than zero.
|
|
||||||
/// // For example, use 2 for quadratic, or 3 for cubic interpolation in
|
|
||||||
/// // the V direction. This defaults to 2, if not specified.
|
|
||||||
/// vDegree = 2,
|
/// vDegree = 2,
|
||||||
/// })
|
/// )
|
||||||
/// ```
|
/// ```
|
||||||
#[stdlib {
|
#[stdlib {
|
||||||
name = "loft",
|
name = "loft",
|
||||||
|
keywords = true,
|
||||||
|
unlabeled_first = true,
|
||||||
|
arg_docs = {
|
||||||
|
sketches = "Which sketches to loft. Must include at least 2 sketches.",
|
||||||
|
v_degree = "Degree of the interpolation. Must be greater than zero. For example, use 2 for quadratic, or 3 for cubic interpolation in the V direction. This defaults to 2, if not specified.",
|
||||||
|
bez_approximate_rational = "Attempt to approximate rational curves (such as arcs) using a bezier. This will remove banding around interpolations between arcs and non-arcs. It may produce errors in other scenarios Over time, this field won't be necessary.",
|
||||||
|
base_curve_index = "This can be set to override the automatically determined topological base curve, which is usually the first section encountered.",
|
||||||
|
tolerance = "Tolerance for the loft operation.",
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
async fn inner_loft(
|
async fn inner_loft(
|
||||||
sketches: Vec<Sketch>,
|
sketches: Vec<Sketch>,
|
||||||
data: Option<LoftData>,
|
v_degree: NonZeroU32,
|
||||||
|
bez_approximate_rational: bool,
|
||||||
|
base_curve_index: Option<u32>,
|
||||||
|
tolerance: Option<f64>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<Solid>, KclError> {
|
) -> Result<Box<Solid>, KclError> {
|
||||||
@ -152,20 +141,15 @@ async fn inner_loft(
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the loft data.
|
|
||||||
let data = data.unwrap_or_default();
|
|
||||||
|
|
||||||
let id = exec_state.id_generator.next_uuid();
|
let id = exec_state.id_generator.next_uuid();
|
||||||
args.batch_modeling_cmd(
|
args.batch_modeling_cmd(
|
||||||
id,
|
id,
|
||||||
ModelingCmd::from(mcmd::Loft {
|
ModelingCmd::from(mcmd::Loft {
|
||||||
section_ids: sketches.iter().map(|group| group.id).collect(),
|
section_ids: sketches.iter().map(|group| group.id).collect(),
|
||||||
base_curve_index: data.base_curve_index,
|
base_curve_index,
|
||||||
bez_approximate_rational: data.bez_approximate_rational.unwrap_or(false),
|
bez_approximate_rational,
|
||||||
tolerance: LengthUnit(data.tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
|
tolerance: LengthUnit(tolerance.unwrap_or(default_tolerance(&args.ctx.settings.units))),
|
||||||
v_degree: data
|
v_degree,
|
||||||
.v_degree
|
|
||||||
.unwrap_or_else(|| std::num::NonZeroU32::new(DEFAULT_V_DEGREE).unwrap()),
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -34,6 +34,10 @@ pub async fn rem(_exec_state: &mut ExecState, args: Args) -> Result<KclValue, Kc
|
|||||||
tags = ["math"],
|
tags = ["math"],
|
||||||
keywords = true,
|
keywords = true,
|
||||||
unlabeled_first = true,
|
unlabeled_first = true,
|
||||||
|
arg_docs = {
|
||||||
|
num = "The number which will be divided by `divisor`.",
|
||||||
|
divisor = "The number which will divide `num`.",
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
fn inner_rem(num: i64, divisor: i64) -> Result<i64, KclError> {
|
fn inner_rem(num: i64, divisor: i64) -> Result<i64, KclError> {
|
||||||
Ok(num % divisor)
|
Ok(num % divisor)
|
||||||
|
Reference in New Issue
Block a user