diff --git a/.github/workflows/pullrequest.yml b/.github/workflows/pullrequest.yml index bf73c7304..746fa211a 100644 --- a/.github/workflows/pullrequest.yml +++ b/.github/workflows/pullrequest.yml @@ -18,6 +18,9 @@ jobs: steps: - uses: dtolnay/rust-toolchain@1.87.0 + - name: Enable symlinks on Windows + if: runner.os == 'Windows' + run: git config --global core.symlinks true - uses: actions/checkout@v4 with: submodules: true @@ -165,6 +168,9 @@ jobs: steps: - uses: dtolnay/rust-toolchain@1.87.0 + - name: Enable symlinks on Windows + if: runner.os == 'Windows' + run: git config --global core.symlinks true - uses: actions/checkout@v4 with: submodules: true diff --git a/Cargo.lock b/Cargo.lock index bc3a291ff..878083a1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1336,8 +1336,6 @@ dependencies = [ [[package]] name = "js-sys" version = "0.3.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dc6f6450b3f6d4ed5b16327f38fed626d375a886159ca555bd7822c0c3a5a6" dependencies = [ "once_cell", "wasm-bindgen", @@ -3189,8 +3187,6 @@ dependencies = [ [[package]] name = "wasm-bindgen" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60722a937f594b7fde9adb894d7c092fc1bb6612897c46368d18e7a20208eff2" dependencies = [ "cfg-if", "once_cell", @@ -3202,8 +3198,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-cli-support" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a855c0fac6939d61ef9c27e1a436edf4ffdfa0bf63862dee3c1555f6d23b009" dependencies = [ "anyhow", "base64", @@ -3220,8 +3214,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" version = "0.4.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a89f4650b770e4521aa6573724e2aed4704372151bd0de9d16a3bbabb87441a" dependencies = [ "cfg-if", "futures-util", @@ -3234,8 +3226,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac8c6395094b6b91c4af293f4c79371c163f9a6f56184d2c9a85f5a95f3950" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3244,8 +3234,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3fabce6159dc20728033842636887e4877688ae94382766e00b180abac9d60" dependencies = [ "bumpalo", "proc-macro2", @@ -3257,8 +3245,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0e091bdb824da87dc01d967388880d017a0a9bc4f3bdc0d86ee9f9336e3bb5" dependencies = [ "unicode-ident", ] @@ -3266,8 +3252,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-test" version = "0.3.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e6fc7a6f61926fa909ee570d4ca194e264545ebbbb4ffd63ac07ba921bff447" dependencies = [ "async-trait", "cast", @@ -3288,8 +3272,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" version = "0.3.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f745a117245c232859f203d6c8d52c72d4cfc42de7e668c147ca6b3e45f1157e" dependencies = [ "proc-macro2", "quote", @@ -3299,8 +3281,6 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-shared" version = "0.2.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f88e7ae201cc7c291da857532eb1c8712e89494e76ec3967b9805221388e938" [[package]] name = "wasm-encoder" @@ -3412,8 +3392,6 @@ dependencies = [ [[package]] name = "web-sys" version = "0.3.90" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705eceb4ce901230f8625bd1d665128056ccbe4b7408faa625eec1ba80f59a97" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/test/src/sql_counter.rs b/test/src/sql_counter.rs index 46672e018..482bfe2ea 100644 --- a/test/src/sql_counter.rs +++ b/test/src/sql_counter.rs @@ -15,7 +15,7 @@ impl DurableObject for SqlCounter { fn new(state: State, _env: Env) -> Self { let sql = state.storage().sql(); // Create table if it does not exist. Note: `exec` is synchronous. - sql.exec("CREATE TABLE IF NOT EXISTS counter(value INTEGER);", None) + sql.exec("CREATE TABLE IF NOT EXISTS counter(value INTEGER);", []) .expect("create table"); Self { sql } } @@ -43,15 +43,15 @@ impl SqlCounter { let rows: Vec = self .sql - .exec("SELECT value FROM counter LIMIT 1;", None)? + .exec("SELECT value FROM counter LIMIT 1;", [])? .to_array()?; let current = rows.first().map_or(0, |r| r.value); let next = current + 1; // Upsert new value – simplest way: delete and insert again. - self.sql.exec("DELETE FROM counter;", None)?; + self.sql.exec("DELETE FROM counter;", [])?; self.sql - .exec("INSERT INTO counter(value) VALUES (?);", vec![next.into()])?; + .exec("INSERT INTO counter(value) VALUES (?);", [next.into()])?; Response::ok(format!("SQL counter is now {next}")) } @@ -77,9 +77,9 @@ impl SqlCounter { }; // Store the safe value - self.sql.exec("DELETE FROM counter;", None)?; + self.sql.exec("DELETE FROM counter;", [])?; self.sql - .exec("INSERT INTO counter(value) VALUES (?);", vec![safe_value])?; + .exec("INSERT INTO counter(value) VALUES (?);", [safe_value])?; Response::ok(format!("Successfully stored large value: {large_value}")) } diff --git a/test/src/sql_iterator.rs b/test/src/sql_iterator.rs index 019c0b63d..474e25dc4 100644 --- a/test/src/sql_iterator.rs +++ b/test/src/sql_iterator.rs @@ -68,18 +68,18 @@ impl DurableObject for SqlIterator { // Create table and seed with test data sql.exec( "CREATE TABLE IF NOT EXISTS products(id INTEGER PRIMARY KEY, name TEXT, price REAL, in_stock INTEGER);", - None, + [], ).expect("create table"); sql.exec( "CREATE TABLE IF NOT EXISTS blob_data(id INTEGER PRIMARY KEY, name TEXT, data BLOB);", - None, + [], ) .expect("create blob table"); // Check if we need to seed data let count: Vec = sql - .exec("SELECT COUNT(*) as count FROM products;", None) + .exec("SELECT COUNT(*) as count FROM products;", []) .expect("count query") .to_array() .expect("count result"); @@ -103,14 +103,14 @@ impl DurableObject for SqlIterator { for (name, price, in_stock) in products { sql.exec( "INSERT INTO products(name, price, in_stock) VALUES (?, ?, ?);", - vec![name.into(), price.into(), i32::from(in_stock).into()], + [name.into(), price.into(), i32::from(in_stock).into()], ) .expect("insert product"); } } let blob_count: Vec = sql - .exec("SELECT COUNT(*) as count FROM blob_data;", None) + .exec("SELECT COUNT(*) as count FROM blob_data;", []) .expect("blob count query") .to_array() .expect("blob count result"); @@ -135,7 +135,7 @@ impl DurableObject for SqlIterator { for (name, data) in blob_test_data { sql.exec( "INSERT INTO blob_data(name, data) VALUES (?, ?);", - vec![name.into(), SqlStorageValue::Blob(data)], + [name.into(), SqlStorageValue::Blob(data)], ) .expect("insert blob data"); } @@ -162,7 +162,7 @@ impl DurableObject for SqlIterator { impl SqlIterator { fn handle_next(&self) -> Result { - let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", None)?; + let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", [])?; let mut results = Vec::new(); let iterator = cursor.next::(); @@ -190,7 +190,7 @@ impl SqlIterator { } fn handle_raw(&self) -> Result { - let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", None)?; + let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", [])?; let mut results = Vec::new(); let column_names = cursor.column_names(); @@ -216,7 +216,7 @@ impl SqlIterator { } fn handle_next_invalid(&self) -> Result { - let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", None)?; + let cursor = self.sql.exec("SELECT * FROM products ORDER BY id;", [])?; let mut results = Vec::new(); let iterator = cursor.next::(); @@ -244,9 +244,7 @@ impl SqlIterator { } fn handle_blob_next(&self) -> Result { - let cursor = self - .sql - .exec("SELECT * FROM blob_data ORDER BY id;", None)?; + let cursor = self.sql.exec("SELECT * FROM blob_data ORDER BY id;", [])?; let mut results = Vec::new(); let iterator = cursor.raw(); @@ -285,9 +283,7 @@ impl SqlIterator { } fn handle_blob_raw(&self) -> Result { - let cursor = self - .sql - .exec("SELECT * FROM blob_data ORDER BY id;", None)?; + let cursor = self.sql.exec("SELECT * FROM blob_data ORDER BY id;", [])?; let mut results = Vec::new(); let column_names = cursor.column_names(); @@ -341,18 +337,18 @@ impl SqlIterator { // Insert test data self.sql.exec( "INSERT INTO blob_data(name, data) VALUES (?, ?);", - vec![test_name.into(), SqlStorageValue::Blob(test_data.clone())], + [test_name.into(), SqlStorageValue::Blob(test_data.clone())], )?; // Read it back using both methods (raw iterator approach for both) let cursor_next = self.sql.exec( "SELECT * FROM blob_data WHERE name = ? ORDER BY id DESC LIMIT 1;", - vec![test_name.into()], + [test_name.into()], )?; let cursor_raw = self.sql.exec( "SELECT * FROM blob_data WHERE name = ? ORDER BY id DESC LIMIT 1;", - vec![test_name.into()], + [test_name.into()], )?; let mut results = Vec::new(); @@ -400,10 +396,8 @@ impl SqlIterator { } // Clean up test data - self.sql.exec( - "DELETE FROM blob_data WHERE name = ?;", - vec![test_name.into()], - )?; + self.sql + .exec("DELETE FROM blob_data WHERE name = ?;", [test_name.into()])?; let response_body = format!("blob-roundtrip test results:\n{}", results.join("\n")); diff --git a/worker/src/d1/mod.rs b/worker/src/d1/mod.rs index e27046804..b74225613 100644 --- a/worker/src/d1/mod.rs +++ b/worker/src/d1/mod.rs @@ -49,7 +49,10 @@ impl D1Database { /// Batch execute one or more statements against the database. /// /// Returns the results in the same order as the provided statements. - pub async fn batch(&self, statements: Vec) -> Result> { + pub async fn batch( + &self, + statements: impl IntoIterator, + ) -> Result> { let statements = statements.into_iter().map(|s| s.0).collect::(); let results = JsFuture::from(self.0.batch(statements)?).await; let results = cast_to_d1_error(results)?; diff --git a/worker/src/durable.rs b/worker/src/durable.rs index 446866b49..055f8eec6 100644 --- a/worker/src/durable.rs +++ b/worker/src/durable.rs @@ -361,7 +361,10 @@ impl Storage { } /// Retrieves the values associated with each of the provided keys. - pub async fn get_multiple(&self, keys: Vec>) -> Result { + pub async fn get_multiple, I: IntoIterator>( + &self, + keys: I, + ) -> Result { let keys = self.inner.get_multiple( keys.into_iter() .map(|key| JsValue::from(key.deref())) @@ -426,7 +429,10 @@ impl Storage { /// Deletes the provided keys and their associated values. Returns a count of the number of /// key-value pairs deleted. - pub async fn delete_multiple(&self, keys: Vec>) -> Result { + pub async fn delete_multiple( + &self, + keys: impl IntoIterator>, + ) -> Result { let fut: JsFuture = self .inner .delete_multiple( @@ -590,7 +596,10 @@ impl Transaction { .map_err(Error::from) } - pub async fn get_multiple(&self, keys: Vec>) -> Result { + pub async fn get_multiple, D: Deref>( + &self, + keys: I, + ) -> Result { let keys = self.inner.get_multiple( keys.into_iter() .map(|key| JsValue::from(key.deref())) @@ -629,7 +638,10 @@ impl Transaction { .map_err(Error::from) } - pub async fn delete_multiple(&self, keys: Vec>) -> Result { + pub async fn delete_multiple, D: Deref>( + &self, + keys: I, + ) -> Result { let fut: JsFuture = self .inner .delete_multiple( diff --git a/worker/src/r2/builder.rs b/worker/src/r2/builder.rs index e339695ff..e4888730f 100644 --- a/worker/src/r2/builder.rs +++ b/worker/src/r2/builder.rs @@ -408,8 +408,8 @@ impl ListOptionsBuilder<'_> { /// .await?; /// } /// ``` - pub fn include(mut self, include: Vec) -> Self { - self.include = Some(include); + pub fn include(mut self, include: impl IntoIterator) -> Self { + self.include = Some(include.into_iter().collect()); self } diff --git a/worker/src/r2/mod.rs b/worker/src/r2/mod.rs index 8b1dab9ee..09f7aeefe 100644 --- a/worker/src/r2/mod.rs +++ b/worker/src/r2/mod.rs @@ -87,7 +87,10 @@ impl Bucket { /// pairs globally. /// /// Up to 1000 keys may be deleted per call. - pub async fn delete_multiple(&self, keys: Vec>) -> Result<()> { + pub async fn delete_multiple( + &self, + keys: impl IntoIterator>, + ) -> Result<()> { let fut: JsFuture = self .inner .delete_multiple(keys.into_iter().map(|key| JsValue::from(&*key)).collect())? diff --git a/worker/src/router.rs b/worker/src/router.rs index 625d80a49..f32ff386b 100644 --- a/worker/src/router.rs +++ b/worker/src/router.rs @@ -357,7 +357,12 @@ impl<'a, D: 'a> Router<'a, D> { self } - fn add_handler(&mut self, pattern: &str, func: Handler<'a, D>, methods: Vec) { + fn add_handler( + &mut self, + pattern: &str, + func: Handler<'a, D>, + methods: impl IntoIterator, + ) { for method in methods { self.handlers .entry(method.clone()) diff --git a/worker/src/sql.rs b/worker/src/sql.rs index 50c875a9e..16d813411 100644 --- a/worker/src/sql.rs +++ b/worker/src/sql.rs @@ -201,13 +201,11 @@ impl SqlStorage { pub fn exec( &self, query: &str, - bindings: impl Into>>, + bindings: impl IntoIterator, ) -> Result { let array = Array::new(); - if let Some(bindings) = bindings.into() { - for v in bindings { - array.push(&v.into()); - } + for v in bindings { + array.push(&v.into()); } let cursor = self.inner.exec(query, array).map_err(Error::from)?; Ok(SqlCursor { inner: cursor }) @@ -220,13 +218,11 @@ impl SqlStorage { pub fn exec_raw( &self, query: &str, - bindings: impl Into>>, + bindings: impl IntoIterator, ) -> Result { let array = Array::new(); - if let Some(bindings) = bindings.into() { - for v in bindings { - array.push(&v); - } + for v in bindings { + array.push(&v); } let cursor = self.inner.exec(query, array).map_err(Error::from)?; Ok(SqlCursor { inner: cursor }) diff --git a/worker/src/websocket.rs b/worker/src/websocket.rs index 08b1608d5..239c34510 100644 --- a/worker/src/websocket.rs +++ b/worker/src/websocket.rs @@ -76,19 +76,19 @@ impl WebSocket { /// Response::error("never got a message echoed back :(", 500) /// ``` pub async fn connect(url: Url) -> Result { - WebSocket::connect_with_protocols(url, None).await + WebSocket::connect_with_protocols(url, std::iter::empty::<&str>()).await } /// Attempts to establish a [`WebSocket`] connection to the provided [`Url`] and protocol. /// /// # Example: /// ```rust,ignore - /// let ws = WebSocket::connect_with_protocols("wss://echo.zeb.workers.dev/".parse()?, Some(vec!["GiggleBytes"])).await?; + /// let ws = WebSocket::connect_with_protocols("wss://echo.zeb.workers.dev/".parse()?, ["GiggleBytes"]).await?; /// /// ``` pub async fn connect_with_protocols( mut url: Url, - protocols: Option>, + protocols: impl IntoIterator>, ) -> Result { let scheme: String = match url.scheme() { "ws" => "http".into(), @@ -103,12 +103,14 @@ impl WebSocket { let mut req = Request::new(url.as_str(), Method::Get)?; req.headers_mut()?.set("upgrade", "websocket")?; - match protocols { - None => {} - Some(v) => { - req.headers_mut()? - .set("Sec-WebSocket-Protocol", v.join(",").as_str())?; - } + let protocols: Vec<_> = protocols.into_iter().collect(); + if !protocols.is_empty() { + let joined: String = protocols + .iter() + .map(AsRef::as_ref) + .collect::>() + .join(","); + req.headers_mut()?.set("Sec-WebSocket-Protocol", &joined)?; } #[cfg(not(feature = "http"))]