Fix to never have undefined iteration order and lint against it (#4665)
This commit is contained in:
@ -77,6 +77,9 @@ 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.77", features = ["websocket"] }
|
||||||
|
|
||||||
|
[workspace.lints.clippy]
|
||||||
|
iter_over_hash_type = "warn"
|
||||||
|
|
||||||
[[test]]
|
[[test]]
|
||||||
name = "executor"
|
name = "executor"
|
||||||
path = "tests/executor/main.rs"
|
path = "tests/executor/main.rs"
|
||||||
|
|||||||
@ -27,3 +27,6 @@ anyhow = "1.0.93"
|
|||||||
expectorate = "1.1.0"
|
expectorate = "1.1.0"
|
||||||
pretty_assertions = "1.4.1"
|
pretty_assertions = "1.4.1"
|
||||||
rustfmt-wrapper = "0.2.1"
|
rustfmt-wrapper = "0.2.1"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|||||||
@ -13,3 +13,6 @@ pico-args = "0.5.0"
|
|||||||
serde = { version = "1.0.214", features = ["derive"] }
|
serde = { version = "1.0.214", features = ["derive"] }
|
||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.41.1", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|||||||
@ -21,3 +21,6 @@ kittycad = { workspace = true, features = ["clap"] }
|
|||||||
kittycad-modeling-cmds = { workspace = true }
|
kittycad-modeling-cmds = { workspace = true }
|
||||||
tokio = { version = "1.41", features = ["full", "time", "rt", "tracing"] }
|
tokio = { version = "1.41", features = ["full", "time", "rt", "tracing"] }
|
||||||
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
|
uuid = { version = "1.11.0", features = ["v4", "js", "serde"] }
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|||||||
@ -121,6 +121,9 @@ pretty_assertions = "1.4.1"
|
|||||||
tokio = { version = "1.41.1", features = ["rt-multi-thread", "macros", "time"] }
|
tokio = { version = "1.41.1", features = ["rt-multi-thread", "macros", "time"] }
|
||||||
twenty-twenty = "0.8.0"
|
twenty-twenty = "0.8.0"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "compiler_benchmark_criterion"
|
name = "compiler_benchmark_criterion"
|
||||||
harness = false
|
harness = false
|
||||||
|
|||||||
@ -22,6 +22,9 @@ members = ["."]
|
|||||||
[profile.release]
|
[profile.release]
|
||||||
debug = 1
|
debug = 1
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "parser"
|
name = "parser"
|
||||||
path = "fuzz_targets/parser.rs"
|
path = "fuzz_targets/parser.rs"
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use convert_case::Casing;
|
use convert_case::Casing;
|
||||||
use handlebars::Renderable;
|
use handlebars::Renderable;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
@ -271,7 +272,7 @@ fn init_handlebars() -> Result<handlebars::Handlebars<'static>> {
|
|||||||
Ok(hbs)
|
Ok(hbs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_index(combined: &HashMap<String, Box<dyn StdLibFn>>) -> Result<()> {
|
fn generate_index(combined: &IndexMap<String, Box<dyn StdLibFn>>) -> Result<()> {
|
||||||
let hbs = init_handlebars()?;
|
let hbs = init_handlebars()?;
|
||||||
|
|
||||||
let mut functions = Vec::new();
|
let mut functions = Vec::new();
|
||||||
|
|||||||
@ -213,7 +213,12 @@ impl EngineConnection {
|
|||||||
WebSocketResponse::Success(SuccessWebSocketResponse {
|
WebSocketResponse::Success(SuccessWebSocketResponse {
|
||||||
resp: OkWebSocketResponseData::ModelingBatch { responses },
|
resp: OkWebSocketResponseData::ModelingBatch { responses },
|
||||||
..
|
..
|
||||||
}) => {
|
}) =>
|
||||||
|
{
|
||||||
|
#[expect(
|
||||||
|
clippy::iter_over_hash_type,
|
||||||
|
reason = "modeling command uses a HashMap and keys are random, so we don't really have a choice"
|
||||||
|
)]
|
||||||
for (resp_id, batch_response) in responses {
|
for (resp_id, batch_response) in responses {
|
||||||
let id: uuid::Uuid = (*resp_id).into();
|
let id: uuid::Uuid = (*resp_id).into();
|
||||||
match batch_response {
|
match batch_response {
|
||||||
|
|||||||
@ -463,6 +463,10 @@ pub trait EngineManager: std::fmt::Debug + Send + Sync + 'static {
|
|||||||
responses: HashMap<uuid::Uuid, BatchResponse>,
|
responses: HashMap<uuid::Uuid, BatchResponse>,
|
||||||
) -> Result<OkWebSocketResponseData, crate::errors::KclError> {
|
) -> Result<OkWebSocketResponseData, crate::errors::KclError> {
|
||||||
// Iterate over the responses and check for errors.
|
// Iterate over the responses and check for errors.
|
||||||
|
#[expect(
|
||||||
|
clippy::iter_over_hash_type,
|
||||||
|
reason = "modeling command uses a HashMap and keys are random, so we don't really have a choice"
|
||||||
|
)]
|
||||||
for (cmd_id, resp) in responses.iter() {
|
for (cmd_id, resp) in responses.iter() {
|
||||||
match resp {
|
match resp {
|
||||||
BatchResponse::Success { response } => {
|
BatchResponse::Success { response } => {
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
//! The executor for the AST.
|
//! The executor for the AST.
|
||||||
|
|
||||||
use std::{
|
use std::{collections::HashSet, sync::Arc};
|
||||||
collections::{HashMap, HashSet},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use async_recursion::async_recursion;
|
use async_recursion::async_recursion;
|
||||||
@ -193,7 +190,7 @@ impl EnvironmentRef {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
||||||
pub struct Environment {
|
pub struct Environment {
|
||||||
bindings: HashMap<String, KclValue>,
|
bindings: IndexMap<String, KclValue>,
|
||||||
parent: Option<EnvironmentRef>,
|
parent: Option<EnvironmentRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +200,7 @@ impl Environment {
|
|||||||
pub fn root() -> Self {
|
pub fn root() -> Self {
|
||||||
Self {
|
Self {
|
||||||
// Prelude
|
// Prelude
|
||||||
bindings: HashMap::from([
|
bindings: IndexMap::from([
|
||||||
("ZERO".to_string(), KclValue::from_number(0.0, NO_META)),
|
("ZERO".to_string(), KclValue::from_number(0.0, NO_META)),
|
||||||
("QUARTER_TURN".to_string(), KclValue::from_number(90.0, NO_META)),
|
("QUARTER_TURN".to_string(), KclValue::from_number(90.0, NO_META)),
|
||||||
("HALF_TURN".to_string(), KclValue::from_number(180.0, NO_META)),
|
("HALF_TURN".to_string(), KclValue::from_number(180.0, NO_META)),
|
||||||
@ -215,7 +212,7 @@ impl Environment {
|
|||||||
|
|
||||||
pub fn new(parent: EnvironmentRef) -> Self {
|
pub fn new(parent: EnvironmentRef) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bindings: HashMap::new(),
|
bindings: IndexMap::new(),
|
||||||
parent: Some(parent),
|
parent: Some(parent),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -770,8 +767,8 @@ pub struct Sketch {
|
|||||||
/// The starting path.
|
/// The starting path.
|
||||||
pub start: BasePath,
|
pub start: BasePath,
|
||||||
/// Tag identifiers that have been declared in this sketch.
|
/// Tag identifiers that have been declared in this sketch.
|
||||||
#[serde(default, skip_serializing_if = "HashMap::is_empty")]
|
#[serde(default, skip_serializing_if = "IndexMap::is_empty")]
|
||||||
pub tags: HashMap<String, TagIdentifier>,
|
pub tags: IndexMap<String, TagIdentifier>,
|
||||||
/// The original id of the sketch. This stays the same even if the sketch is
|
/// The original id of the sketch. This stays the same even if the sketch is
|
||||||
/// is sketched on face etc.
|
/// is sketched on face etc.
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
|
|||||||
@ -25,11 +25,10 @@ pub mod types;
|
|||||||
pub mod units;
|
pub mod units;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
pub use args::Args;
|
pub use args::Args;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use parse_display::{Display, FromStr};
|
use parse_display::{Display, FromStr};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
@ -167,8 +166,8 @@ pub fn get_stdlib_fn(name: &str) -> Option<Box<dyn StdLibFn>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdLib {
|
pub struct StdLib {
|
||||||
pub fns: HashMap<String, Box<dyn StdLibFn>>,
|
pub fns: IndexMap<String, Box<dyn StdLibFn>>,
|
||||||
pub kcl_fns: HashMap<String, Box<dyn KclStdLibFn>>,
|
pub kcl_fns: IndexMap<String, Box<dyn KclStdLibFn>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for StdLib {
|
impl std::fmt::Debug for StdLib {
|
||||||
@ -198,7 +197,7 @@ impl StdLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the combined hashmaps.
|
// Get the combined hashmaps.
|
||||||
pub fn combined(&self) -> HashMap<String, Box<dyn StdLibFn>> {
|
pub fn combined(&self) -> IndexMap<String, Box<dyn StdLibFn>> {
|
||||||
let mut combined = self.fns.clone();
|
let mut combined = self.fns.clone();
|
||||||
for (k, v) in self.kcl_fns.clone() {
|
for (k, v) in self.kcl_fns.clone() {
|
||||||
combined.insert(k, v.std_lib());
|
combined.insert(k, v.std_lib());
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
//! Functions related to sketching.
|
//! Functions related to sketching.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use derive_docs::stdlib;
|
use derive_docs::stdlib;
|
||||||
|
use indexmap::IndexMap;
|
||||||
use kcmc::shared::Point2d as KPoint2d; // Point2d is already defined in this pkg, to impl ts_rs traits.
|
use kcmc::shared::Point2d as KPoint2d; // Point2d is already defined in this pkg, to impl ts_rs traits.
|
||||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
|
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::Angle, ModelingCmd};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds as kcmc;
|
||||||
@ -1301,7 +1300,7 @@ pub(crate) async fn inner_start_profile_at(
|
|||||||
}),
|
}),
|
||||||
surface: None,
|
surface: None,
|
||||||
});
|
});
|
||||||
HashMap::from([(tag.name.to_string(), tag_identifier)])
|
IndexMap::from([(tag.name.to_string(), tag_identifier)])
|
||||||
} else {
|
} else {
|
||||||
Default::default()
|
Default::default()
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user