diff --git a/Cargo.toml b/Cargo.toml index cadb230343..7caba831b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ debug = true version = "0.8.2" edition = "2021" # update rust-toolchain.toml too! -rust-version = "1.76.0" +rust-version = "1.77.0" [workspace.dependencies] spacetimedb = { path = "crates/bindings", version = "0.8.2" } diff --git a/crates/bench/Dockerfile b/crates/bench/Dockerfile index 630d71fa81..14229dc430 100644 --- a/crates/bench/Dockerfile +++ b/crates/bench/Dockerfile @@ -3,7 +3,7 @@ # See the README for commands to run. # sync with: ../../rust-toolchain.toml -FROM rust:1.76.0 +FROM rust:1.77.0 RUN apt-get update && \ apt-get install -y valgrind protobuf-compiler bash && \ diff --git a/crates/client-api/src/routes/database.rs b/crates/client-api/src/routes/database.rs index 2e354d8150..4adb3ef941 100644 --- a/crates/client-api/src/routes/database.rs +++ b/crates/client-api/src/routes/database.rs @@ -23,7 +23,7 @@ use spacetimedb::messages::control_db::{Database, DatabaseInstance}; use spacetimedb::sql::execute::execute; use spacetimedb_lib::address::AddressForUrl; use spacetimedb_lib::identity::AuthCtx; -use spacetimedb_lib::name::{self, DnsLookupResponse, DomainName, DomainParsingError, PublishOp, PublishResult}; +use spacetimedb_lib::name::{self, DnsLookupResponse, DomainName, PublishOp, PublishResult}; use spacetimedb_lib::recovery::{RecoveryCode, RecoveryCodeResponse}; use spacetimedb_lib::sats::WithTypespace; use std::collections::HashMap; @@ -38,8 +38,7 @@ use crate::routes::subscribe::generate_random_address; use crate::util::{ByteStringBody, NameOrAddress}; use crate::{log_and_500, ControlStateDelegate, DatabaseDef, NodeDelegate}; -#[derive(derive_more::From)] -pub(crate) struct DomainParsingRejection(pub(crate) DomainParsingError); +pub(crate) struct DomainParsingRejection; impl IntoResponse for DomainParsingRejection { fn into_response(self) -> axum::response::Response { @@ -608,7 +607,7 @@ pub async fn dns( Path(DNSParams { database_name }): Path, Query(DNSQueryParams {}): Query, ) -> axum::response::Result { - let domain = database_name.parse().map_err(DomainParsingRejection)?; + let domain = database_name.parse().map_err(|_| DomainParsingRejection)?; let address = ctx.lookup_address(&domain).map_err(log_and_500)?; let response = if let Some(address) = address { DnsLookupResponse::Success { domain, address } @@ -645,7 +644,7 @@ pub async fn register_tld( // so, unless you are the owner, this will fail, hence not using get_or_create let auth = auth_or_unauth(auth)?; - let tld = tld.parse::().map_err(DomainParsingRejection)?.into(); + let tld = tld.parse::().map_err(|_| DomainParsingRejection)?.into(); let result = ctx.register_tld(&auth.identity, tld).await.map_err(log_and_500)?; Ok(axum::Json(result)) } @@ -906,7 +905,7 @@ pub async fn set_name( return Err((StatusCode::UNAUTHORIZED, "Identity does not own database.").into()); } - let domain = domain.parse().map_err(DomainParsingRejection)?; + let domain = domain.parse().map_err(|_| DomainParsingRejection)?; let response = ctx .create_dns_record(&auth.identity, &domain, &address) .await diff --git a/crates/client-api/src/util.rs b/crates/client-api/src/util.rs index 9e05f4bb0d..493e814b4f 100644 --- a/crates/client-api/src/util.rs +++ b/crates/client-api/src/util.rs @@ -96,7 +96,7 @@ impl NameOrAddress { domain: None, }), Self::Name(name) => { - let domain = name.parse().map_err(DomainParsingRejection)?; + let domain = name.parse().map_err(|_| DomainParsingRejection)?; let address = ctx.lookup_address(&domain).map_err(log_and_500)?; match address { Some(address) => Ok(ResolvedAddress { diff --git a/crates/core/src/db/ostorage/hashmap_object_db.rs b/crates/core/src/db/ostorage/hashmap_object_db.rs index fddda14f0e..eb2efd5b6c 100644 --- a/crates/core/src/db/ostorage/hashmap_object_db.rs +++ b/crates/core/src/db/ostorage/hashmap_object_db.rs @@ -136,7 +136,12 @@ impl ObjectDB for HashMapObjectDB { let filename = hex::encode(&hash.data[1..]); let path = self.root.join(folder).join(filename); - let mut unsynced = OpenOptions::new().write(true).create(true).open(path).unwrap(); + let mut unsynced = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(path) + .unwrap(); unsynced.write_all(&bytes).unwrap(); self.unsynced.push(unsynced); diff --git a/crates/core/src/subscription/module_subscription_manager.rs b/crates/core/src/subscription/module_subscription_manager.rs index d1684d4a7a..a30893304c 100644 --- a/crates/core/src/subscription/module_subscription_manager.rs +++ b/crates/core/src/subscription/module_subscription_manager.rs @@ -41,7 +41,7 @@ impl SubscriptionManager { } pub fn query(&self, hash: &QueryHash) -> Option { - self.queries.get(hash).map(Arc::clone) + self.queries.get(hash).cloned() } pub fn num_queries(&self) -> usize { diff --git a/crates/core/src/vm.rs b/crates/core/src/vm.rs index de5498ccdc..ec84c68c4e 100644 --- a/crates/core/src/vm.rs +++ b/crates/core/src/vm.rs @@ -19,7 +19,6 @@ use spacetimedb_vm::iterators::RelIter; use spacetimedb_vm::program::ProgramVm; use spacetimedb_vm::rel_ops::RelOps; use spacetimedb_vm::relation::{MemTable, RelValue, Table}; -use std::ops::Bound; use std::sync::Arc; pub enum TxMode<'a> { @@ -88,17 +87,9 @@ pub fn build_query<'a>( } else { // For multi-col constraints, these are stored as bounds of product values, // so we need to project these into single-col bounds and compare against the column. - // TODO: replace with `bound.map(...)` once stable. - fn map U>(bound: Bound, f: F) -> Bound { - match bound { - Bound::Unbounded => Bound::Unbounded, - Bound::Included(x) => Bound::Included(f(x)), - Bound::Excluded(x) => Bound::Excluded(f(x)), - } - } // Project start/end `Bound`s to `Bound>`s. - let start_bound = map(bounds.0.as_ref(), |av| &av.as_product().unwrap().elements); - let end_bound = map(bounds.1.as_ref(), |av| &av.as_product().unwrap().elements); + let start_bound = bounds.0.as_ref().map(|av| &av.as_product().unwrap().elements); + let end_bound = bounds.1.as_ref().map(|av| &av.as_product().unwrap().elements); // Construct the query: let iter = result.select(move |row| { // Go through each column position, @@ -107,8 +98,8 @@ pub fn build_query<'a>( // All columns must match to include the row, // which is essentially the same as a big `AND` of `ColumnOp`s. Ok(cols.iter().enumerate().all(|(idx, col)| { - let start_bound = map(start_bound, |pv| &pv[idx]); - let end_bound = map(end_bound, |pv| &pv[idx]); + let start_bound = start_bound.map(|pv| &pv[idx]); + let end_bound = end_bound.map(|pv| &pv[idx]); let read_col = row.read_column(col.idx()).unwrap(); (start_bound, end_bound).contains(&*read_col) })) diff --git a/crates/lib/src/name.rs b/crates/lib/src/name.rs index 4a6df269bd..d3dabf9593 100644 --- a/crates/lib/src/name.rs +++ b/crates/lib/src/name.rs @@ -531,7 +531,14 @@ fn ensure_domain_segment(input: &str) -> Result<(), ParseError> { } fn ensure_domain_tld(input: &str) -> Result<(), ParseError> { - DomainTld::try_from(input).map(|_| ()) + let DomainSegment(input) = DomainSegment::try_from(input)?; + if input.contains('/') { + Err(ParseError::ContainsSlash { part: input.to_owned() }) + } else if is_address(input) { + Err(ParseError::Address { part: input.to_owned() }) + } else { + Ok(()) + } } /// Parsing helper to validate (path) segments of a [`DomainName`], without @@ -555,22 +562,3 @@ impl<'a> TryFrom<&'a str> for DomainSegment<'a> { } } } - -/// Parsing helper to validate that a [`DomainSegment`] is a valid [`Tld`], -/// without consuming the input. -struct DomainTld<'a>(&'a str); - -impl<'a> TryFrom<&'a str> for DomainTld<'a> { - type Error = ParseError; - - fn try_from(value: &'a str) -> Result { - let DomainSegment(value) = DomainSegment::try_from(value)?; - if value.contains('/') { - Err(ParseError::ContainsSlash { part: value.to_owned() }) - } else if is_address(value) { - Err(ParseError::Address { part: value.to_owned() }) - } else { - Ok(Self(value)) - } - } -} diff --git a/crates/sats/src/hash.rs b/crates/sats/src/hash.rs index e97726af2a..2ead6ae9a1 100644 --- a/crates/sats/src/hash.rs +++ b/crates/sats/src/hash.rs @@ -76,8 +76,6 @@ impl fmt::Debug for Hash { } } -pub struct HashFromHexError(usize); - impl hex::FromHex for Hash { type Error = hex::FromHexError; diff --git a/crates/sdk/src/global_connection.rs b/crates/sdk/src/global_connection.rs index a4abfd763a..e96c39da4e 100644 --- a/crates/sdk/src/global_connection.rs +++ b/crates/sdk/src/global_connection.rs @@ -118,7 +118,7 @@ thread_local! { /// and accesses to the client cache state (e.g. by `TableType::iter`) /// will inspect the `CURRENT_STATE`, rather than the most-recent state /// in `global_connection::CONNECTION`. - pub(crate) static CURRENT_STATE: RefCell> = RefCell::new(None); + pub(crate) static CURRENT_STATE: RefCell> = const { RefCell::new(None) }; } /// If `CURRENT_STATE` is bound, diff --git a/crates/standalone/Dockerfile b/crates/standalone/Dockerfile index 1bcdac61b3..7afb64b71a 100644 --- a/crates/standalone/Dockerfile +++ b/crates/standalone/Dockerfile @@ -3,7 +3,7 @@ ARG CARGO_PROFILE=release -FROM rust:1.76.0 AS chef +FROM rust:1.77.0 AS chef RUN rust_target=$(rustc -vV | awk '/^host:/{ print $2 }') && \ curl https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-$rust_target.tgz -fL | tar xz -C $CARGO_HOME/bin RUN cargo binstall -y cargo-chef@0.1.56 diff --git a/crates/standalone/src/lib.rs b/crates/standalone/src/lib.rs index f1897da749..76d862941a 100644 --- a/crates/standalone/src/lib.rs +++ b/crates/standalone/src/lib.rs @@ -152,11 +152,7 @@ fn create_keys(public_key_path: &Path, private_key_path: &Path) -> anyhow::Resul } fn get_key_path(env: &str) -> Option { - let Some(path) = std::env::var_os(env) else { - return None; - }; - let path = std::path::PathBuf::from(path); - Some(path) + std::env::var_os(env).map(std::path::PathBuf::from) } #[async_trait] diff --git a/crates/table/src/pointer_map.rs b/crates/table/src/pointer_map.rs index 984fdd664a..64a595a769 100644 --- a/crates/table/src/pointer_map.rs +++ b/crates/table/src/pointer_map.rs @@ -180,6 +180,7 @@ impl PointerMap { // due to `PointerMap::maintains_invariants` being undefined. // Easily solved by including a stub definition. #[cfg(not(debug_assertions))] +#[allow(dead_code)] impl PointerMap { fn maintains_invariants(&self) -> bool { unreachable!( diff --git a/crates/table/src/row_type_visitor.rs b/crates/table/src/row_type_visitor.rs index 2295913c8c..da465dd22b 100644 --- a/crates/table/src/row_type_visitor.rs +++ b/crates/table/src/row_type_visitor.rs @@ -364,10 +364,7 @@ pub struct VarLenVisitorProgram { #[inline] fn next_vlr_offset(program: &[Insn], instr_ptr: &mut u16, read_tag: impl Fn(u16) -> u8) -> Option { loop { - let Some(insn) = program.get(*instr_ptr as usize) else { - return None; - }; - match insn { + match program.get(*instr_ptr as usize)? { Insn::VisitOffset(offset) => { *instr_ptr += 1; return Some(PageOffset(*offset)); diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5acd93581a..b7cf178ad1 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] # change crates/standalone/Dockerfile and rust-version in Cargo.toml too! -channel = "1.76.0" +channel = "1.77.0" profile = "default" targets = ["wasm32-unknown-unknown"]