don't
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

style: pendantic clippy --fix

Signed-off-by: tjh <x@tjh.dev>

tjh cab06f74 5eb21129

+177 -137
+7 -1
crates/atproto/src/aturi.rs
··· 17 17 } 18 18 19 19 impl<'a> AtUri<'a> { 20 + #[must_use] 20 21 pub const fn did(&self) -> Option<&'a Did> { 21 22 match self.authority { 22 23 Authority::Did(did) => Some(did), ··· 25 24 } 26 25 } 27 26 27 + #[must_use] 28 28 pub const fn handle(&self) -> Option<&'a Handle> { 29 29 match self.authority { 30 30 Authority::Handle(handle) => Some(handle), ··· 33 31 } 34 32 } 35 33 34 + #[must_use] 36 35 pub const fn collection_str(&self) -> Option<&str> { 37 36 match self.collection { 38 37 Some(collection) => Some(collection.as_str()), ··· 48 45 Handle(&'a Handle), 49 46 } 50 47 51 - impl<'a> Authority<'a> { 48 + impl Authority<'_> { 49 + #[must_use] 52 50 pub const fn is_did(&self) -> bool { 53 51 matches!(self, Self::Did(_)) 54 52 } 55 53 54 + #[must_use] 56 55 pub const fn is_handle(&self) -> bool { 57 56 matches!(self, Self::Handle(_)) 58 57 } 59 58 59 + #[must_use] 60 60 pub const fn as_str(&self) -> &str { 61 61 match self { 62 62 Self::Did(did) => did.as_str(),
+17 -18
crates/atproto/src/did.rs
··· 1 - //! ATmosphere specific DID. 1 + //! `ATmosphere` specific DID. 2 2 //! 3 3 use core::{borrow, fmt, mem, ops}; 4 4 ··· 16 16 17 17 impl Did { 18 18 fn new<D: AsRef<str> + ?Sized>(did: &D) -> &Self { 19 - unsafe { &*(did.as_ref() as *const str as *const Self) } 19 + unsafe { &*(std::ptr::from_ref::<str>(did.as_ref()) as *const Self) } 20 20 } 21 21 22 22 const fn new_boxed(did: Box<str>) -> Box<Self> { ··· 29 29 /// 30 30 /// Panics if `s` is not a valid DID. 31 31 /// 32 + #[must_use] 32 33 pub fn from_static(did: &'static str) -> &'static Self { 33 34 validate_did(did).expect("hard-coded did should be valid"); 34 35 Self::new(did) ··· 50 49 /// 51 50 pub fn parse<D: AsRef<str> + ?Sized>(did: &D) -> Result<&Self, Error> { 52 51 validate_did(did.as_ref())?; 53 - Ok(Did::new(did)) 52 + Ok(Self::new(did)) 54 53 } 55 54 56 55 /// DID type. Always returns "did". ··· 64 63 /// assert_eq!(did.typ(), "did"); 65 64 /// ``` 66 65 /// 67 - pub fn typ(&self) -> &str { 66 + #[must_use] 67 + pub fn typ(&self) -> &'static str { 68 68 assert_eq!( 69 69 &self.inner[..4], 70 70 "did:", ··· 88 86 /// assert_eq!(did.method(), "web"); 89 87 /// ``` 90 88 /// 89 + #[must_use] 91 90 pub fn method(&self) -> &str { 92 91 &self.inner[4..self.method_terminator()] 93 92 } ··· 107 104 /// assert_eq!(did.ident(), "tjh.dev"); 108 105 /// ``` 109 106 /// 107 + #[must_use] 110 108 pub fn ident(&self) -> &str { 111 109 &self.inner[1 + self.method_terminator()..] 112 110 } 113 111 114 112 /// Get the DID as a string slice. 115 113 #[inline] 114 + #[must_use] 116 115 pub const fn as_str(&self) -> &str { 117 116 &self.inner 118 117 } 119 118 120 119 /// Convert to a `Box<Did>`. 121 - pub fn into_boxed(&self) -> Box<Did> { 122 - Did::new_boxed(self.inner.to_owned().into_boxed_str()) 120 + #[must_use] 121 + pub fn into_boxed(&self) -> Box<Self> { 122 + Self::new_boxed(self.inner.to_owned().into_boxed_str()) 123 123 } 124 124 125 125 fn method_terminator(&self) -> usize { ··· 228 222 229 223 impl From<Box<Did>> for Box<str> { 230 224 fn from(value: Box<Did>) -> Self { 231 - unsafe { mem::transmute::<Box<Did>, Box<str>>(value) } 225 + unsafe { mem::transmute::<Box<Did>, Self>(value) } 232 226 } 233 227 } 234 228 ··· 264 258 } 265 259 266 260 fn validate_method(method: &str) -> Result<(), Error> { 267 - match !method.is_empty() && method.as_bytes().iter().all(|v| v.is_ascii_lowercase()) { 268 - true => Ok(()), 269 - false => Err(Error::InvalidMethod(method.into())), 270 - } 261 + if !method.is_empty() && method.as_bytes().iter().all(u8::is_ascii_lowercase) { Ok(()) } else { Err(Error::InvalidMethod(method.into())) } 271 262 } 272 263 273 264 fn validate_ident(ident: &str) -> Result<(), Error> { 274 - match !ident.is_empty() 265 + if !ident.is_empty() 275 266 && ident 276 267 .as_bytes() 277 268 .iter() 278 - .all(|v| v.is_ascii_alphanumeric() || [b'.', b'_', b':', b'%', b'-'].contains(v)) 279 - && !ident.ends_with([':', '%']) 280 - { 281 - true => Ok(()), 282 - false => Err(Error::InvalidIdent(ident.into())), 283 - } 269 + .all(|v| v.is_ascii_alphanumeric() || [b'.', b'_', b':', b'%', b'-'].contains(v)) && !ident.ends_with([':', '%']) { Ok(()) } else { Err(Error::InvalidIdent(ident.into())) } 284 270 285 271 // @TODO Validate percent encoding in ident. 286 272 } ··· 296 298 Self { inner } 297 299 } 298 300 301 + #[must_use] 299 302 pub fn from_static(did: &'static str) -> Self { 300 303 validate_did(did).expect("hard-coded did should be valid"); 301 304 let inner = did.into();
+8 -4
crates/atproto/src/handle.rs
··· 1 1 use core::{fmt, mem, ops}; 2 2 3 - /// An ATproto handle. 3 + /// An `ATproto` handle. 4 4 #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)] 5 5 #[repr(transparent)] 6 6 pub struct Handle { ··· 9 9 10 10 impl Handle { 11 11 fn new<S: AsRef<str> + ?Sized>(s: &S) -> &Self { 12 - unsafe { &*(s.as_ref() as *const str as *const Self) } 12 + unsafe { &*(std::ptr::from_ref::<str>(s.as_ref()) as *const Self) } 13 13 } 14 14 15 15 fn new_owned(handle: Box<str>) -> Box<Self> { 16 - unsafe { mem::transmute::<Box<str>, Box<Handle>>(handle) } 16 + unsafe { mem::transmute::<Box<str>, Box<Self>>(handle) } 17 17 } 18 18 19 19 /// Create a `Handle` from an `&'static str`. Panics if the handle is not 20 20 /// valid. 21 + #[must_use] 21 22 pub fn from_static(s: &'static str) -> &'static Self { 22 23 validate_handle(s).expect("`s` should be a valid Handle"); 23 24 Self::new(s) ··· 30 29 } 31 30 32 31 #[inline] 32 + #[must_use] 33 33 pub const fn as_str(&self) -> &str { 34 34 &self.inner 35 35 } 36 36 37 37 #[inline] 38 + #[must_use] 38 39 pub const fn len(&self) -> usize { 39 40 self.inner.len() 40 41 } 41 42 42 43 #[inline] 44 + #[must_use] 43 45 pub const fn is_empty(&self) -> bool { 44 46 assert!(!self.inner.is_empty()); 45 47 false ··· 82 78 } 83 79 84 80 impl ToOwned for Handle { 85 - type Owned = Box<Handle>; 81 + type Owned = Box<Self>; 86 82 #[inline] 87 83 fn to_owned(&self) -> Self::Owned { 88 84 Self::new_owned(self.inner.to_owned().into_boxed_str())
+6 -2
crates/atproto/src/nsid.rs
··· 8 8 9 9 impl Nsid { 10 10 fn new<N: AsRef<str> + ?Sized>(s: &N) -> &Self { 11 - unsafe { &*(s.as_ref() as *const str as *const Nsid) } 11 + unsafe { &*(std::ptr::from_ref::<str>(s.as_ref()) as *const Self) } 12 12 } 13 13 14 14 fn new_owned(nsid: Box<str>) -> Box<Self> { 15 15 unsafe { mem::transmute::<Box<str>, Box<Self>>(nsid) } 16 16 } 17 17 18 + #[must_use] 18 19 pub fn from_static(s: &'static str) -> &'static Self { 19 20 validate_nsid(s).expect("`s` should be a valid NSID"); 20 21 Self::new(s) ··· 27 26 } 28 27 29 28 #[inline] 29 + #[must_use] 30 30 pub const fn as_str(&self) -> &str { 31 31 &self.inner 32 32 } 33 33 34 34 #[inline] 35 + #[must_use] 35 36 pub const fn len(&self) -> usize { 36 37 self.inner.len() 37 38 } 38 39 39 40 #[inline] 41 + #[must_use] 40 42 pub const fn is_empty(&self) -> bool { 41 43 assert!(!self.inner.is_empty()); 42 44 false ··· 75 71 } 76 72 77 73 impl ToOwned for Nsid { 78 - type Owned = Box<Nsid>; 74 + type Owned = Box<Self>; 79 75 #[inline] 80 76 fn to_owned(&self) -> Self::Owned { 81 77 Self::new_owned(self.inner.to_owned().into_boxed_str())
+15 -14
crates/atproto/src/tid.rs
··· 56 56 /// Panics if `micros` is greater than [`Self::MAX_TIMESTAMP`]. 57 57 /// 58 58 pub const fn set_micros(&mut self, micros: u64) { 59 - if micros > Self::MAX_TIMESTAMP { 60 - panic!("TID timestamp must be in the range 0..=9007199254740991 microseconds"); 61 - } 59 + assert!(micros <= Self::MAX_TIMESTAMP, "TID timestamp must be in the range 0..=9007199254740991 microseconds"); 62 60 self.0 |= (micros & MASK_TIMESTAMP) << BITS_CLOCK_ID; 63 61 } 64 62 ··· 67 69 /// Panics if `clock_id` is greater than [`Self::MAX_CLOCK_ID`]. 68 70 /// 69 71 pub const fn set_clock_id(&mut self, clock_id: u16) { 70 - if clock_id > Self::MAX_CLOCK_ID { 71 - panic!("TID clock ID must be in the range 0..=1023"); 72 - } 73 - self.0 |= (clock_id as u64) & MASK_CLOCK_ID 72 + assert!(clock_id <= Self::MAX_CLOCK_ID, "TID clock ID must be in the range 0..=1023"); 73 + self.0 |= (clock_id as u64) & MASK_CLOCK_ID; 74 74 } 75 75 76 76 /// Create a new TID with the specified timestamp and clock ID. ··· 80 84 /// * `micros` exceeds [`Self::MAX_TIMESTAMP`]. 81 85 /// * `clock_id` exceeds [`Self::MAX_CLOCK_ID`] 82 86 /// 87 + #[must_use] 83 88 pub const fn new(micros: u64, clock_id: u16) -> Self { 84 - let mut new = Tid(0); 89 + let mut new = Self(0); 85 90 new.set_micros(micros); 86 91 new.set_clock_id(clock_id); 87 92 new ··· 106 109 /// * `seconds` exceeds [`Self::MAX_TIMESTAMP`] when converted to microseconds. 107 110 /// * `clock_id` exceeds [`Self::MAX_CLOCK_ID`] 108 111 /// 112 + #[must_use] 109 113 pub const fn from_secs(seconds: u64, clock_id: u16) -> Self { 110 114 Self::new(seconds * 1_000_000, clock_id) 111 115 } ··· 142 144 /// assert_eq!(Tid::MAX.micros(), 9007199254740991); 143 145 /// ``` 144 146 /// 145 - pub fn micros(&self) -> u64 { 147 + #[must_use] 148 + pub const fn micros(&self) -> u64 { 146 149 (self.0 >> BITS_CLOCK_ID) & Self::MAX_TIMESTAMP 147 150 } 148 151 ··· 155 156 /// assert_eq!(Tid::MAX.clock_id(), 1023); 156 157 /// ``` 157 158 /// 158 - pub fn clock_id(&self) -> u16 { 159 + #[must_use] 160 + pub const fn clock_id(&self) -> u16 { 159 161 // CONVERSION: Clock ID mask ensures this will always produce an equivalent u16. 160 162 (self.0 & MASK_CLOCK_ID) as _ 161 163 } ··· 190 190 /// 191 191 pub fn set_datetime(&mut self, dt: time::OffsetDateTime) { 192 192 let micros = dt.unix_timestamp_nanos() / 1000; 193 - self.set_micros(micros.try_into().unwrap()) 193 + self.set_micros(micros.try_into().unwrap()); 194 194 } 195 195 196 196 /// Create a TID from the specified [`time::OffsetDateTime`] and clock ID. ··· 199 199 /// 200 200 /// Panics if `dt` is later than 2255-06-05 23:47:34.740991 +00:00:00. 201 201 /// 202 + #[must_use] 202 203 pub fn from_datetime(dt: time::OffsetDateTime, clock_id: u16) -> Self { 203 204 let micros = dt.unix_timestamp_nanos() / 1000; 204 205 Self::new(micros.try_into().unwrap(), clock_id) 205 206 } 206 207 207 208 /// Convert the TID to a [`time::OffsetDateTime`] 209 + #[must_use] 208 210 pub fn as_datetime(&self) -> time::OffsetDateTime { 209 211 time::OffsetDateTime::from_unix_timestamp_nanos(self.nanos()) 210 212 .expect("2^53 microseconds is less than MAX for OffsetDateTime") ··· 311 309 312 310 impl TidClock { 313 311 /// Create a new TID clock with the specified ID. 312 + #[must_use] 314 313 pub const fn with_id(clock_id: u16) -> Self { 315 - if clock_id > Tid::MAX_CLOCK_ID { 316 - panic!("TID clock ID must be in the range 0..=1023"); 317 - } 314 + assert!(clock_id <= Tid::MAX_CLOCK_ID, "TID clock ID must be in the range 0..=1023"); 318 315 319 316 Self { 320 317 id: clock_id,
+2 -1
crates/auth/src/jwt.rs
··· 49 49 } 50 50 51 51 impl Header { 52 - pub fn new(alg: Algorithm, crv: Option<Curve>) -> Self { 52 + #[must_use] 53 + pub const fn new(alg: Algorithm, crv: Option<Curve>) -> Self { 53 54 Self { 54 55 typ: Type::JWT, 55 56 alg,
+1 -1
crates/auth/src/types.rs
··· 80 80 } 81 81 82 82 #[allow(unused)] 83 - pub fn set_application_type(mut self, application_type: ApplicationType) -> Self { 83 + pub const fn set_application_type(mut self, application_type: ApplicationType) -> Self { 84 84 self.application_type = application_type; 85 85 self 86 86 }
+7 -9
crates/auth/src/verification_key.rs
··· 170 170 171 171 impl VerificationKey for ParsedPublicKey { 172 172 fn verify_sig(&self, message: &[u8], signature: &[u8]) -> Result<(), super::Unspecified> { 173 - ParsedPublicKey::verify_sig(&self, message, signature).map_err(|_| super::Unspecified) 173 + Self::verify_sig(self, message, signature).map_err(|_| super::Unspecified) 174 174 } 175 175 } 176 176 ··· 194 194 195 195 let (key_type, bytes) = match (maybe_key_type, &maybe_key_data) { 196 196 (Some("ssh-ed25519"), Some(Ok(bytes))) => { 197 - let (key_type, remaining) = prefixed_bytes(&bytes).or_raise(make_error)?; 197 + let (key_type, remaining) = prefixed_bytes(bytes).or_raise(make_error)?; 198 198 require_match(key_type, b"ssh-ed25519")?; 199 199 200 200 let (key_data, remaining) = prefixed_bytes(remaining).or_raise(make_error)?; ··· 203 203 ("ssh-ed25519", Cow::Borrowed(key_data)) 204 204 } 205 205 (Some("ecdsa-sha2-nistp256"), Some(Ok(bytes))) => { 206 - let (key_type, remaining) = prefixed_bytes(&bytes)?; 206 + let (key_type, remaining) = prefixed_bytes(bytes)?; 207 207 require_match(key_type, b"ecdsa-sha2-nistp256")?; 208 208 209 209 let (thing, remaining) = prefixed_bytes(remaining)?; ··· 215 215 ("ecdsa-sha2-nistp256", Cow::Borrowed(key_data)) 216 216 } 217 217 (Some("ecdsa-sha2-nistp384"), Some(Ok(bytes))) => { 218 - let (key_type, remaining) = prefixed_bytes(&bytes)?; 218 + let (key_type, remaining) = prefixed_bytes(bytes)?; 219 219 require_match(key_type, b"ecdsa-sha2-nistp384")?; 220 220 221 221 let (thing, remaining) = prefixed_bytes(remaining)?; ··· 227 227 ("ecdsa-sha2-nistp384", Cow::Borrowed(key_data)) 228 228 } 229 229 (Some("ecdsa-sha2-nistp521"), Some(Ok(bytes))) => { 230 - let (key_type, remaining) = prefixed_bytes(&bytes)?; 230 + let (key_type, remaining) = prefixed_bytes(bytes)?; 231 231 require_match(key_type, b"ecdsa-sha2-nistp521")?; 232 232 233 233 let (thing, remaining) = prefixed_bytes(remaining)?; ··· 239 239 ("ecdsa-sha2-nistp521", Cow::Borrowed(key_data)) 240 240 } 241 241 (Some("ssh-rsa"), Some(Ok(bytes))) => { 242 - let (key_type, remaining) = prefixed_bytes(&bytes)?; 242 + let (key_type, remaining) = prefixed_bytes(bytes)?; 243 243 require_match(key_type, b"ssh-rsa")?; 244 244 245 245 let (exponent, remaining) = prefixed_bytes(remaining)?; ··· 262 262 ("rsa-sha2-512", Cow::Owned(serialized.as_ref().to_vec())) 263 263 } 264 264 (Some(_), Some(Err(_))) => { 265 - exn::bail!(KeyRejected::new(format!( 266 - "Failed to decode base64-encoded key data" 267 - ))); 265 + exn::bail!(KeyRejected::new("Failed to decode base64-encoded key data".to_string())); 268 266 } 269 267 (Some(key_type), _) => { 270 268 exn::bail!(KeyRejected::new(format!(
+1 -1
crates/credential-helper/src/commands/auth.rs
··· 24 24 println!( 25 25 "Using DID: {}", 26 26 active_account.if_supports_color(Stream::Stdout, |t| t.green()) 27 - ) 27 + ); 28 28 } 29 29 None => println!("No active account"), 30 30 }
+1 -3
crates/credential-helper/src/commands/git_credential.rs
··· 99 99 account_did.if_supports_color(Stderr, |text| text.green()) 100 100 ); 101 101 102 - if !self.method.contains(&"ssh".to_string()) { 103 - panic!("unsupported method"); 104 - } 102 + assert!(self.method.contains(&"ssh".to_string()), "unsupported method"); 105 103 106 104 // Build a list of the public keys associated with the current active DID. 107 105 let empty = HashSet::new();
+1 -1
crates/credential-helper/src/main.rs
··· 2 2 mod config; 3 3 4 4 use clap::{Parser, Subcommand}; 5 - use commands::*; 5 + use commands::{Auth, GitCredential, GitSetup}; 6 6 use tracing_subscriber::{EnvFilter, layer::SubscriberExt as _, util::SubscriberInitExt as _}; 7 7 8 8 pub trait RunCommand {
+1 -1
crates/git-service/src/state.rs
··· 143 143 } 144 144 } 145 145 146 - pub(crate) async fn resolve_path( 146 + pub async fn resolve_path( 147 147 base: &std::path::Path, 148 148 parts: &mut Parts, 149 149 ) -> Result<PathBuf, PathRejection> {
+9 -12
crates/git-service/src/util.rs
··· 123 123 } 124 124 Ok(output) => { 125 125 let status = output.status; 126 - match std::str::from_utf8(&output.stderr) { 127 - Ok(stderr) => tracing::error!( 128 - ?status, 129 - "error waiting for git child process. stderr:\n{stderr}" 130 - ), 131 - Err(_) => tracing::error!( 132 - ?status, 133 - "error waiting for git child process. stderr:\n{:?}\n{}", 134 - &output.stderr, 135 - String::from_utf8_lossy(&output.stderr) 136 - ), 137 - } 126 + if let Ok(stderr) = std::str::from_utf8(&output.stderr) { tracing::error!( 127 + ?status, 128 + "error waiting for git child process. stderr:\n{stderr}" 129 + ) } else { tracing::error!( 130 + ?status, 131 + "error waiting for git child process. stderr:\n{:?}\n{}", 132 + &output.stderr, 133 + String::from_utf8_lossy(&output.stderr) 134 + ) } 138 135 false 139 136 } 140 137 Err(error) => {
+4 -1
crates/identity/src/document.rs
··· 23 23 } 24 24 25 25 impl Service { 26 - /// Create a [`Service`] definition for an ATproto PDS from `service_endpoint`. 26 + /// Create a [`Service`] definition for an `ATproto` PDS from `service_endpoint`. 27 + #[must_use] 27 28 pub fn atproto_pds(service_endpoint: Url) -> Self { 28 29 Self { 29 30 id: "#atproto_pds".to_string(), ··· 57 56 }) 58 57 } 59 58 59 + #[must_use] 60 60 pub fn primary_alias(&self) -> Option<&str> { 61 61 self.also_known_as 62 62 .first() 63 63 .and_then(|at_uri| at_uri.domain()) 64 64 } 65 65 66 + #[must_use] 66 67 pub fn atproto_pds(&self) -> Option<&Service> { 67 68 self.service.iter().find(|service| { 68 69 service.id == "#atproto_pds" && service.typ == "AtprotoPersonalDataServer"
+35 -34
crates/identity/src/lib.rs
··· 24 24 &'s self, 25 25 ident: &'a str, 26 26 ) -> BoxFuture<'a, Result<(OwnedDid, DidDocument), ResolveError>> { 27 - match ident.parse::<OwnedDid>() { 28 - Ok(did) => { 29 - async { 30 - let doc = self.resolve_did(&did).await?; 31 - let handle = doc.primary_alias().ok_or(ResolveError::InvalidDocument)?; 27 + if let Ok(did) = ident.parse::<OwnedDid>() { 28 + async { 29 + let doc = self.resolve_did(&did).await?; 30 + let handle = doc.primary_alias().ok_or(ResolveError::InvalidDocument)?; 32 31 33 - // Verify the primary handle in the DID document resolves to 34 - // the DID we were given. 35 - let resolved = self.resolve_handle(handle).await?; 36 - match did == resolved { 37 - true => Ok((did, doc)), 38 - false => Err(ResolveError::BidirectionalFailure), 32 + // Verify the primary handle in the DID document resolves to 33 + // the DID we were given. 34 + let resolved = self.resolve_handle(handle).await?; 35 + if did == resolved { Ok((did, doc)) } else { Err(ResolveError::BidirectionalFailure) } 36 + } 37 + .boxed() 38 + } else { 39 + let handle = ident.trim_start_matches('@'); 40 + async move { 41 + let did = self.resolve_handle(handle).await?; 42 + let doc = self.resolve_did(&did).await?; 43 + 44 + // Verify the document has a matching handle. 45 + for alias in &doc.also_known_as { 46 + if alias.domain().is_some_and(|host| host == ident) { 47 + return Ok((did, doc)); 39 48 } 40 49 } 41 - .boxed() 42 - } 43 - Err(_) => { 44 - let handle = ident.trim_start_matches('@'); 45 - async move { 46 - let did = self.resolve_handle(handle).await?; 47 - let doc = self.resolve_did(&did).await?; 48 50 49 - // Verify the document has a matching handle. 50 - for alias in &doc.also_known_as { 51 - if alias.domain().is_some_and(|host| host == ident) { 52 - return Ok((did, doc)); 53 - } 54 - } 55 - 56 - Err(ResolveError::BidirectionalFailure) 57 - } 58 - .boxed() 51 + Err(ResolveError::BidirectionalFailure) 59 52 } 53 + .boxed() 60 54 } 61 55 } 62 56 ··· 124 130 Self { inner } 125 131 } 126 132 133 + #[must_use] 127 134 pub fn builder() -> ResolverBuilder { 128 135 ResolverBuilder::new() 129 136 } ··· 161 166 /// The underlying [`MockResolver`] is returned along with the type-erased [`Resolver`] to 162 167 /// enable access to [`MockResolver::insert`]. 163 168 /// 164 - pub fn mocked(documents: impl IntoIterator<Item = DidDocument>) -> (Resolver, MockResolver) { 169 + pub fn mocked(documents: impl IntoIterator<Item = DidDocument>) -> (Self, MockResolver) { 165 170 let resolver = MockResolver::new(documents); 166 171 let mocked = resolver.clone(); 167 172 let inner = Arc::new(resolver); 168 - (Resolver { inner }, mocked) 173 + (Self { inner }, mocked) 169 174 } 170 175 } 171 176 ··· 204 209 } 205 210 206 211 impl ResolverBuilder { 212 + #[must_use] 207 213 pub fn new() -> Self { 208 214 Self { 209 215 backend: Default::default(), ··· 217 221 /// Use [`DirectResolver`] as the backend resolver. 218 222 /// 219 223 /// This resolver does not cache DIDs or DID documents. 220 - pub fn direct(mut self) -> Self { 224 + #[must_use] 225 + pub const fn direct(mut self) -> Self { 221 226 self.backend = ResolverBackend::Direct; 222 227 self 223 228 } 224 229 225 230 /// Use [`MemcacheResolver`] as the backend resolver. 226 - pub fn memcache(mut self) -> Self { 231 + #[must_use] 232 + pub const fn memcache(mut self) -> Self { 227 233 self.backend = ResolverBackend::Memcache; 228 234 self 229 235 } ··· 233 235 /// Set the cache capacity for both DIDs and DID documents. 234 236 /// 235 237 /// Ignored if backend resolver does not support caching. 236 - pub fn cache_capacity(mut self, cap: u64) -> Self { 238 + #[must_use] 239 + pub const fn cache_capacity(mut self, cap: u64) -> Self { 237 240 self.cache_capacity = cap; 238 241 self 239 242 } ··· 242 243 /// Set the cache Time-To-Live for both DIDs and DID documents. 243 244 /// 244 245 /// Ignored if backend resolver does not support caching. 245 - pub fn cache_ttl(mut self, ttl: std::time::Duration) -> Self { 246 + #[must_use] 247 + pub const fn cache_ttl(mut self, ttl: std::time::Duration) -> Self { 246 248 self.cache_ttl = ttl; 247 249 self 248 250 } ··· 256 256 self 257 257 } 258 258 259 + #[must_use] 259 260 pub fn build_with(self, http: HttpClient) -> Resolver { 260 261 use resolvers::direct::DirectResolver; 261 262 use resolvers::memcache::MemcacheResolver;
+5 -2
crates/identity/src/resolvers/direct.rs
··· 84 84 } 85 85 86 86 impl DirectResolver<'_, TokioConnectionProvider> { 87 - pub fn builder() -> DirectResolverBuilder<'static> { 87 + #[must_use] 88 + pub const fn builder() -> DirectResolverBuilder<'static> { 88 89 DirectResolverBuilder { 89 90 plc_directory: Cow::Borrowed(DEFAULT_PLC_DIRECTORY), 90 91 } ··· 119 118 impl<'plc> DirectResolverBuilder<'plc> { 120 119 /// Set the PLC directory to use. Must be a well-formed URL. 121 120 /// 122 - /// Defaults to "https://plc.directory". 121 + /// Defaults to "<https://plc.directory>". 122 + #[must_use] 123 123 pub fn plc_directory(mut self, directory: Cow<'plc, str>) -> Self { 124 124 self.plc_directory = directory; 125 125 self 126 126 } 127 127 128 + #[must_use] 128 129 pub fn build_with(self, http: HttpClient) -> DirectResolver<'plc, TokioConnectionProvider> { 129 130 DirectResolver { 130 131 plc: self.plc_directory,
+14 -7
crates/identity/src/resolvers/memcache.rs
··· 41 41 } 42 42 } 43 43 44 - pub fn builder() -> MemcacheResolverBuilder { 44 + #[must_use] 45 + pub const fn builder() -> MemcacheResolverBuilder { 45 46 MemcacheResolverBuilder { 46 47 did_cache_capacity: DEFAULT_DID_CACHE_CAP, 47 48 did_cache_ttl: DEFAULT_DID_CACHE_TTL, ··· 97 96 98 97 impl MemcacheResolverBuilder { 99 98 /// Set the DID cache capacity and the DID document cache capacity. 100 - pub fn capacity(self, capacity: u64) -> Self { 99 + #[must_use] 100 + pub const fn capacity(self, capacity: u64) -> Self { 101 101 self.did_capacity(capacity).doc_capacity(capacity) 102 102 } 103 103 104 104 /// Set the DID cache ttl and the DID document cache ttl. 105 - pub fn ttl(self, ttl: Duration) -> Self { 105 + #[must_use] 106 + pub const fn ttl(self, ttl: Duration) -> Self { 106 107 self.did_ttl(ttl).doc_ttl(ttl) 107 108 } 108 109 109 - pub fn did_capacity(mut self, capacity: u64) -> Self { 110 + #[must_use] 111 + pub const fn did_capacity(mut self, capacity: u64) -> Self { 110 112 self.did_cache_capacity = capacity; 111 113 self 112 114 } 113 115 114 - pub fn doc_capacity(mut self, capacity: u64) -> Self { 116 + #[must_use] 117 + pub const fn doc_capacity(mut self, capacity: u64) -> Self { 115 118 self.doc_cache_capacity = capacity; 116 119 self 117 120 } 118 121 119 - pub fn did_ttl(mut self, ttl: Duration) -> Self { 122 + #[must_use] 123 + pub const fn did_ttl(mut self, ttl: Duration) -> Self { 120 124 self.did_cache_ttl = ttl; 121 125 self 122 126 } 123 127 124 - pub fn doc_ttl(mut self, ttl: Duration) -> Self { 128 + #[must_use] 129 + pub const fn doc_ttl(mut self, ttl: Duration) -> Self { 125 130 self.doc_cache_ttl = ttl; 126 131 self 127 132 }
+5 -2
crates/jetstream/src/client.rs
··· 85 85 Ok(()) 86 86 } 87 87 88 + #[must_use] 88 89 pub fn metrics(&self) -> MetricsData { 89 90 self.metrics.export() 90 91 } ··· 166 165 } 167 166 168 167 impl JetstreamReceiver { 169 - pub(crate) fn new(event_rx: flume::Receiver<Bytes>) -> Self { 168 + pub(crate) const fn new(event_rx: flume::Receiver<Bytes>) -> Self { 170 169 Self { event_rx } 171 170 } 172 171 ··· 181 180 /// Synchronously receive a Jetstream event. 182 181 /// 183 182 /// Returns [`None`] when the Jetstream client is shutdown. 183 + #[must_use] 184 184 pub fn recv(&self) -> Option<JetstreamEvent> { 185 185 let bytes = self.event_rx.recv().ok()?; 186 186 Some(JetstreamEvent::new(bytes)) 187 187 } 188 188 189 189 /// Consume the Jetstream receiver and return the wrapped flume channel receiver. 190 + #[must_use] 190 191 pub fn to_inner(self) -> flume::Receiver<Bytes> { 191 192 self.event_rx 192 193 } ··· 209 206 self.bytes 210 207 } 211 208 212 - fn new(bytes: Bytes) -> Self { 209 + const fn new(bytes: Bytes) -> Self { 213 210 Self { bytes } 214 211 } 215 212 }
+5 -1
crates/jetstream/src/client_config.rs
··· 21 21 impl JetstreamConfig { 22 22 /// Create default a [`JetstreamConfig`] connecting to jetstream{1,2}.us-east.bsky.network 23 23 /// instances. 24 + #[must_use] 24 25 pub fn us_east() -> Self { 25 26 Self { 26 27 client_options: ClientOptions { ··· 37 36 38 37 /// Create default a [`JetstreamConfig`] connecting to jetstream{1,2}.us-west.bsky.network 39 38 /// instances. 39 + #[must_use] 40 40 pub fn us_west() -> Self { 41 41 Self { 42 42 client_options: ClientOptions { ··· 51 49 } 52 50 } 53 51 52 + #[must_use] 54 53 pub fn connect(self) -> (JetstreamClient, JetstreamReceiver, JetstreamTask) { 55 54 let (event_tx, event_rx) = flume::bounded(8); 56 55 let (client_tx, client_rx) = flume::bounded(8); ··· 78 75 (client, receiver, task) 79 76 } 80 77 81 - pub fn with_cursor(mut self, cursor: Option<u128>) -> Self { 78 + #[must_use] 79 + pub const fn with_cursor(mut self, cursor: Option<u128>) -> Self { 82 80 self.subscriber_options.cursor = cursor; 83 81 self 84 82 }
+8
crates/jetstream/src/de.rs
··· 148 148 } 149 149 150 150 impl<'a> Event<'a> { 151 + #[must_use] 151 152 pub const fn did(&'a self) -> &'a Did { 152 153 match self { 153 154 Self::Commit(commit) => commit.did(), ··· 157 156 } 158 157 } 159 158 159 + #[must_use] 160 160 pub const fn ts(&self) -> OffsetDateTime { 161 161 match self { 162 162 Self::Commit(commit) => commit.ts(), ··· 175 173 } 176 174 177 175 impl<'a> CommitEvent<'a> { 176 + #[must_use] 178 177 pub const fn ts(&self) -> OffsetDateTime { 179 178 match self { 180 179 Self::Create(commit) => commit.ts, ··· 184 181 } 185 182 } 186 183 184 + #[must_use] 187 185 pub const fn did(&'a self) -> &'a Did { 188 186 match self { 189 187 Self::Create(commit) => commit.did, ··· 194 190 } 195 191 196 192 #[inline] 193 + #[must_use] 197 194 pub const fn did_str(&'a self) -> &'a str { 198 195 self.did().as_str() 199 196 } 200 197 198 + #[must_use] 201 199 pub const fn collection(&self) -> &str { 202 200 match self { 203 201 Self::Create(commit) => commit.collection, ··· 208 202 } 209 203 } 210 204 205 + #[must_use] 211 206 pub const fn rkey(&self) -> &str { 212 207 match self { 213 208 Self::Create(commit) => commit.rkey, ··· 217 210 } 218 211 } 219 212 213 + #[must_use] 220 214 pub const fn rev(&self) -> &str { 221 215 match self { 222 216 Self::Create(commit) => commit.rev,
+1 -1
crates/jetstream/src/main.rs
··· 52 52 Some(value) if value < 0 => { 53 53 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); 54 54 let offset = Duration::from_secs(value.unsigned_abs()); 55 - Some((now - offset).as_micros()) 55 + Some(now.checked_sub(offset).unwrap().as_micros()) 56 56 } 57 57 Some(value) => Some(value.unsigned_abs().into()), 58 58 None => None,
+2
crates/jetstream/src/metrics.rs
··· 32 32 } 33 33 34 34 impl Metrics { 35 + #[must_use] 35 36 pub fn new() -> Self { 36 37 Self::default() 37 38 } 38 39 39 40 /// Create a clone of the metrics data. 41 + #[must_use] 40 42 pub fn export(&self) -> MetricsData { 41 43 self.inner.lock().unwrap().clone() 42 44 }
+9 -5
crates/jetstream/src/subscriber_options.rs
··· 29 29 30 30 /// Repository DIDs to filter which records are received. 31 31 /// 32 - /// Maximum: 10_000 32 + /// Maximum: `10_000` 33 33 pub wanted_dids: HashSet<OwnedDid>, 34 34 35 35 /// Maximum message size in bytes the subscriber wants to receive. ··· 80 80 } 81 81 82 82 /// Get the normalized maximum message size. 83 + #[must_use] 83 84 pub fn max_message_size(&self) -> i64 { 84 85 normalize_max_message_size(self.max_message_size_bytes) 85 86 } 86 87 87 88 /// Construct the Jetstream subscribe URL, returning a tuple of the URL and a boolean 88 89 /// indicating whether the client should send an options update message on connect. 90 + #[must_use] 89 91 pub fn subscribe_url(&self, url: &url::Url) -> (url::Url, bool) { 90 92 let mut url = url.to_owned(); 91 93 url.set_path("/subscribe"); ··· 123 121 (url, false) 124 122 } 125 123 126 - /// Present the SubscriberOptions as a [`SubscriberSourcedMessage`] for serialization. 127 - pub fn as_subscriber_sourced_message<'a>(&'a self) -> SubscriberSourcedMessage<'a> { 124 + /// Present the `SubscriberOptions` as a [`SubscriberSourcedMessage`] for serialization. 125 + #[must_use] 126 + pub fn as_subscriber_sourced_message(&self) -> SubscriberSourcedMessage<'_> { 128 127 SubscriberSourcedMessage::OptionsUpdate(self.into()) 129 128 } 130 129 ··· 174 171 } 175 172 } 176 173 177 - fn normalize_max_message_size(value: i64) -> i64 { 174 + const fn normalize_max_message_size(value: i64) -> i64 { 178 175 value.abs() 179 176 } 180 177 ··· 188 185 OptionsUpdate(OptionsUpdate<'a>), 189 186 } 190 187 191 - impl<'a> SubscriberSourcedMessage<'a> { 188 + impl SubscriberSourcedMessage<'_> { 192 189 /// Serialize the [`SubscriberSourcedMessage`] to JSON. 190 + #[must_use] 193 191 pub fn to_json(&self) -> String { 194 192 serde_json::to_string(self).expect("SubscriberSourcedMessage should be serializable") 195 193 }
+4 -7
crates/jetstream/src/task.rs
··· 58 58 59 59 impl Jitter for f32 { 60 60 fn jitter(&self, frac: f32) -> Self { 61 - self * (1.0 + 2.0 * frac * (fastrand::f32() - 0.5)) 61 + self * (2.0 * frac).mul_add(fastrand::f32() - 0.5, 1.0) 62 62 } 63 63 } 64 64 65 65 impl Jitter for Duration { 66 66 fn jitter(&self, frac: f32) -> Self { 67 - Duration::from_secs_f32(self.as_secs_f32().jitter(frac).abs()) 67 + Self::from_secs_f32(self.as_secs_f32().jitter(frac).abs()) 68 68 } 69 69 } 70 70 ··· 212 212 state.metrics.modify(|mut data| data.messages_received += 1); 213 213 if let Err(error) = event_tx.send_async(message).await { 214 214 let payload = error.into_inner(); 215 - match std::str::from_utf8(&payload) { 216 - Ok(payload) => tracing::error!(%payload, "Failed to dispatch event to channel"), 217 - Err(_) => tracing::error!(?payload, "Failed to dispatch event to channel"), 218 - } 215 + if let Ok(payload) = std::str::from_utf8(&payload) { tracing::error!(%payload, "Failed to dispatch event to channel") } else { tracing::error!(?payload, "Failed to dispatch event to channel") } 219 216 break 'outer; 220 217 } 221 218 ··· 326 329 fn rewind_cursor(options: &Mutex<SubscriberOptions>, amount: Duration) { 327 330 let mut options = options.lock().unwrap(); 328 331 if let Some(value) = &mut options.cursor { 329 - *value = value.saturating_sub(amount.as_micros()) 332 + *value = value.saturating_sub(amount.as_micros()); 330 333 } 331 334 } 332 335
+1 -1
crates/knot/src/cli.rs
··· 86 86 87 87 impl Arguments { 88 88 pub fn to_knot_config(&self) -> Result<KnotConfiguration, Error> { 89 - let Arguments { 89 + let Self { 90 90 name, 91 91 owner, 92 92 repos: repo_path,
+4 -7
crates/knot/src/main.rs
··· 73 73 assert!(git_config_global_set("core.hooksPath", &arguments.hooks)?); 74 74 assert!(git_config_global_set( 75 75 "receive.advertisePushOptions", 76 - match arguments.require_signed_push { 77 - true => "true", 78 - false => "false", 79 - } 76 + if arguments.require_signed_push { "true" } else { "false" } 80 77 )?); 81 78 82 79 let database = { ··· 122 125 // The knot needs to know the sockets we've bound the private API. 123 126 let private_addrs = private_listeners 124 127 .iter() 125 - .map(|listener| listener.local_addr()) 128 + .map(tokio::net::TcpListener::local_addr) 126 129 .collect::<Result<Vec<_>, std::io::Error>>()?; 127 130 128 131 tracing::info!(?private_addrs, "bound internal API"); ··· 205 208 let mut sigterm = signal::unix::signal(SignalKind::terminate())?; 206 209 207 210 tokio::select! { 208 - Ok(_) = signal::ctrl_c() => { 211 + Ok(()) = signal::ctrl_c() => { 209 212 eprintln!(); 210 213 tracing::info!("ctrl+c received, shutting down ..."); 211 214 }, 212 - Some(_) = sigterm.recv() => { 215 + Some(()) = sigterm.recv() => { 213 216 tracing::info!("SIGTERM received, shutting down ..."); 214 217 } 215 218 }
+2 -1
crates/lexicon/src/extra/objectid.rs
··· 18 18 } 19 19 20 20 impl<E> ObjectId<E> { 21 - pub fn id(&self) -> gix_hash::ObjectId { 21 + #[must_use] 22 + pub const fn id(&self) -> gix_hash::ObjectId { 22 23 self.inner 23 24 } 24 25 }
+2
crates/lexicon/src/sh_tangled/repo/archive.rs
··· 42 42 } 43 43 44 44 impl Format { 45 + #[must_use] 45 46 pub const fn as_str(&self) -> &'static str { 46 47 match self { 47 48 Self::TarGz => "tar.gz", ··· 52 51 } 53 52 } 54 53 54 + #[must_use] 55 55 pub const fn as_content_type(&self) -> &'static str { 56 56 match self { 57 57 Self::TarGz => "application/gzip",