diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 1a411762..948fbd6c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,6 +24,29 @@ env: RUST_BACKTRACE: "1" jobs: + lint: + timeout-minutes: 30 + runs-on: ubuntu-22.04 + defaults: + run: + shell: bash + working-directory: rust + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + lfs: true + - uses: Swatinem/rust-cache@v2 + with: + workspaces: rust + - name: Install dependencies + run: | + sudo apt update + sudo apt install -y protobuf-compiler libssl-dev + - name: Run format + run: cargo fmt --all -- --check + - name: Run clippy + run: cargo clippy --all --all-features -- -D warnings linux: timeout-minutes: 30 runs-on: ubuntu-22.04 diff --git a/rust/ffi/node/src/error.rs b/rust/ffi/node/src/error.rs index 924cf544..14c5cc80 100644 --- a/rust/ffi/node/src/error.rs +++ b/rust/ffi/node/src/error.rs @@ -23,7 +23,7 @@ pub enum Error { #[snafu(display("column '{name}' is missing"))] MissingColumn { name: String }, #[snafu(display("{name}: {message}"))] - RangeError { name: String, message: String }, + OutOfRange { name: String, message: String }, #[snafu(display("{index_type} is not a valid index type"))] InvalidIndexType { index_type: String }, diff --git a/rust/ffi/node/src/index/vector.rs b/rust/ffi/node/src/index/vector.rs index 62c57949..9be5efc0 100644 --- a/rust/ffi/node/src/index/vector.rs +++ b/rust/ffi/node/src/index/vector.rs @@ -65,12 +65,10 @@ fn get_index_params_builder( obj.get_opt::(cx, "index_name")? .map(|s| index_builder.index_name(s.value(cx))); - obj.get_opt::(cx, "metric_type")? - .map(|s| MetricType::try_from(s.value(cx).as_str())) - .map(|mt| { - let metric_type = mt.unwrap(); - index_builder.metric_type(metric_type); - }); + if let Some(metric_type) = obj.get_opt::(cx, "metric_type")? { + let metric_type = MetricType::try_from(metric_type.value(cx).as_str()).unwrap(); + index_builder.metric_type(metric_type); + } let num_partitions = obj.get_opt_usize(cx, "num_partitions")?; let max_iters = obj.get_opt_usize(cx, "max_iters")?; @@ -85,23 +83,29 @@ fn get_index_params_builder( index_builder.ivf_params(ivf_params) }); - obj.get_opt::(cx, "use_opq")? - .map(|s| pq_params.use_opq = s.value(cx)); + if let Some(use_opq) = obj.get_opt::(cx, "use_opq")? { + pq_params.use_opq = use_opq.value(cx); + } - obj.get_opt_usize(cx, "num_sub_vectors")? - .map(|s| pq_params.num_sub_vectors = s); + if let Some(num_sub_vectors) = obj.get_opt_usize(cx, "num_sub_vectors")? { + pq_params.num_sub_vectors = num_sub_vectors; + } - obj.get_opt_usize(cx, "num_bits")? - .map(|s| pq_params.num_bits = s); + if let Some(num_bits) = obj.get_opt_usize(cx, "num_bits")? { + pq_params.num_bits = num_bits; + } - obj.get_opt_usize(cx, "max_iters")? - .map(|s| pq_params.max_iters = s); + if let Some(max_iters) = obj.get_opt_usize(cx, "max_iters")? { + pq_params.max_iters = max_iters; + } - obj.get_opt_usize(cx, "max_opq_iters")? - .map(|s| pq_params.max_opq_iters = s); + if let Some(max_opq_iters) = obj.get_opt_usize(cx, "max_opq_iters")? { + pq_params.max_opq_iters = max_opq_iters; + } - obj.get_opt::(cx, "replace")? - .map(|s| index_builder.replace(s.value(cx))); + if let Some(replace) = obj.get_opt::(cx, "replace")? { + index_builder.replace(replace.value(cx)); + } Ok(index_builder) } diff --git a/rust/ffi/node/src/neon_ext/js_object_ext.rs b/rust/ffi/node/src/neon_ext/js_object_ext.rs index 6ed0fa56..88deb915 100644 --- a/rust/ffi/node/src/neon_ext/js_object_ext.rs +++ b/rust/ffi/node/src/neon_ext/js_object_ext.rs @@ -47,15 +47,15 @@ fn f64_to_u32_safe(n: f64, key: &str) -> Result { use conv::*; n.approx_as::().map_err(|e| match e { - FloatError::NegOverflow(_) => Error::RangeError { + FloatError::NegOverflow(_) => Error::OutOfRange { name: key.into(), message: "must be > 0".to_string(), }, - FloatError::PosOverflow(_) => Error::RangeError { + FloatError::PosOverflow(_) => Error::OutOfRange { name: key.into(), message: format!("must be < {}", u32::MAX), }, - FloatError::NotANumber(_) => Error::RangeError { + FloatError::NotANumber(_) => Error::OutOfRange { name: key.into(), message: "not a valid number".to_string(), }, @@ -66,15 +66,15 @@ fn f64_to_usize_safe(n: f64, key: &str) -> Result { use conv::*; n.approx_as::().map_err(|e| match e { - FloatError::NegOverflow(_) => Error::RangeError { + FloatError::NegOverflow(_) => Error::OutOfRange { name: key.into(), message: "must be > 0".to_string(), }, - FloatError::PosOverflow(_) => Error::RangeError { + FloatError::PosOverflow(_) => Error::OutOfRange { name: key.into(), message: format!("must be < {}", usize::MAX), }, - FloatError::NotANumber(_) => Error::RangeError { + FloatError::NotANumber(_) => Error::OutOfRange { name: key.into(), message: "not a valid number".to_string(), }, diff --git a/rust/ffi/node/src/query.rs b/rust/ffi/node/src/query.rs index 1c8e2327..f24f437f 100644 --- a/rust/ffi/node/src/query.rs +++ b/rust/ffi/node/src/query.rs @@ -25,11 +25,11 @@ impl JsQuery { let limit = query_obj .get_opt::(&mut cx, "_limit")? .map(|value| { - let limit = value.value(&mut cx) as u64; - if limit <= 0 { + let limit = value.value(&mut cx); + if limit <= 0.0 { panic!("Limit must be a positive integer"); } - limit + limit as u64 }); let select = query_obj .get_opt::(&mut cx, "_select")? @@ -73,7 +73,7 @@ impl JsQuery { rt.spawn(async move { let mut builder = table - .search(query.map(|q| Float32Array::from(q))) + .search(query.map(Float32Array::from)) .refine_factor(refine_factor) .nprobes(nprobes) .filter(filter) diff --git a/rust/ffi/node/src/table.rs b/rust/ffi/node/src/table.rs index 3c95b2db..c4777a4b 100644 --- a/rust/ffi/node/src/table.rs +++ b/rust/ffi/node/src/table.rs @@ -45,7 +45,7 @@ impl JsTable { let table_name = cx.argument::(0)?.value(&mut cx); let buffer = cx.argument::(1)?; let (batches, schema) = - arrow_buffer_to_record_batch(buffer.as_slice(&mut cx)).or_throw(&mut cx)?; + arrow_buffer_to_record_batch(buffer.as_slice(&cx)).or_throw(&mut cx)?; // Write mode let mode = match cx.argument::(2)?.value(&mut cx).as_str() { @@ -93,7 +93,7 @@ impl JsTable { let buffer = cx.argument::(0)?; let write_mode = cx.argument::(1)?.value(&mut cx); let (batches, schema) = - arrow_buffer_to_record_batch(buffer.as_slice(&mut cx)).or_throw(&mut cx)?; + arrow_buffer_to_record_batch(buffer.as_slice(&cx)).or_throw(&mut cx)?; let rt = runtime(&mut cx)?; let channel = cx.channel(); let mut table = js_table.table.clone(); @@ -186,7 +186,7 @@ impl JsTable { .downcast_or_throw::(&mut cx)?; let value = updates_arg - .get_value(&mut cx, property.clone())? + .get_value(&mut cx, property)? .downcast_or_throw::(&mut cx)?; let property = property.value(&mut cx); @@ -216,7 +216,7 @@ impl JsTable { .map(|(k, v)| (k.as_str(), v.as_str())) .collect::>(); - let predicate = predicate.as_ref().map(|s| s.as_str()); + let predicate = predicate.as_deref(); let update_result = table.update(predicate, updates_arg).await; deferred.settle_with(&channel, move |mut cx| {