···11use jacquard_common::Data;
22use jacquard_common::types::string::AtprotoStr;
33use jacquard_common::types::uri::Uri;
44-use smol_str::SmolStr;
44+use smol_str::{SmolStr, format_smolstr};
5566pub struct Link {
77 /// dotted field path within the record, e.g. `.subject.uri` or `.facets[].features[app.bsky.richtext.facet#link].uri`
···1212/// extract all link targets from a record, with their field paths.
1313///
1414/// paths follow the same convention as constellation:
1515-/// - start with `.` (root-level field `subject` → `.subject`)
1515+/// - start with `.` (root-level field `subject` -> `.subject`)
1616/// - object keys: `{parent}.{key}`
1717/// - plain array elements: `{parent}[]`
1818/// - typed array elements (objects with `$type`): `{parent}[{$type}]`
···5050 _ => None,
5151 });
5252 match type_tag {
5353- Some(t) => format!("{path}[{t}]"),
5454- None => format!("{path}[]"),
5353+ Some(t) => format_smolstr!("{path}[{t}]"),
5454+ None => format_smolstr!("{path}[]"),
5555 }
5656 }
5757- _ => format!("{path}[]"),
5757+ _ => format_smolstr!("{path}[]"),
5858 };
5959 walk(item, &child_path, links);
6060 }
6161 }
6262 Data::Object(obj) => {
6363 for (k, v) in &obj.0 {
6464- walk(v, &format!("{path}.{k}"), links);
6464+ walk(v, &format_smolstr!("{path}.{k}"), links);
6565 }
6666 }
6767 _ => {}
+1-1
src/backlinks/mod.rs
···148148 let mut next_cursor = None;
149149150150 for item in iter {
151151- let (key, _) = item.into_inner().into_diagnostic()?;
151151+ let key = item.key().into_diagnostic()?;
152152 if !key.starts_with(scan_prefix.as_slice()) {
153153 break;
154154 }
+9-13
src/backlinks/store.rs
···5858/// path should include the leading `.` (e.g. `.subject.uri`). always ends with `|`.
5959pub fn reverse_scan_prefix(target: &str, collection: Option<&str>, path: Option<&str>) -> Vec<u8> {
6060 let col_len = collection.map_or(0, |c| c.len() + 1);
6161- let path_len = if collection.is_some() {
6262- path.map_or(0, |p| p.len() + 1)
6363- } else {
6464- 0
6565- };
6161+ let path_len = collection
6262+ .is_some()
6363+ .then(|| path.map_or(0, |p| p.len() + 1))
6464+ .unwrap_or(0);
6665 let mut prefix = Vec::with_capacity(2 + target.len() + 1 + col_len + path_len);
6766 prefix.push(b'r');
6867 prefix.push(SEP);
···9594/// reverse key format: `r|{target}|{collection}|{path}|{did}|{rkey}`
9695/// parses the last four `|`-separated segments from the right.
9796pub fn source_from_reverse_key(key: &[u8]) -> Option<(&str, &str, &str, &str)> {
9898- let rkey_sep = key.iter().rposition(|&b| b == SEP)?;
9999- let rkey = std::str::from_utf8(&key[rkey_sep + 1..]).ok()?;
100100- let did_sep = key[..rkey_sep].iter().rposition(|&b| b == SEP)?;
101101- let did = std::str::from_utf8(&key[did_sep + 1..rkey_sep]).ok()?;
102102- let path_sep = key[..did_sep].iter().rposition(|&b| b == SEP)?;
103103- let path = std::str::from_utf8(&key[path_sep + 1..did_sep]).ok()?;
104104- let col_sep = key[..path_sep].iter().rposition(|&b| b == SEP)?;
105105- let col = std::str::from_utf8(&key[col_sep + 1..path_sep]).ok()?;
9797+ let mut parts = key.rsplit(|&b| b == SEP);
9898+ let rkey = std::str::from_utf8(parts.next()?).ok()?;
9999+ let did = std::str::from_utf8(parts.next()?).ok()?;
100100+ let path = std::str::from_utf8(parts.next()?).ok()?;
101101+ let col = std::str::from_utf8(parts.next()?).ok()?;
106102 Some((col, path, did, rkey))
107103}
108104
+1-1
src/control.rs
···6161/// let hydrant = Hydrant::from_env().await?;
6262///
6363/// tokio::select! {
6464-/// r = hydrant.run() => r,
6464+/// r = hydrant.run()? => r,
6565/// r = hydrant.serve(3000) => r,
6666/// }
6767/// }