Skip to content

Commit 289b4cf

Browse files
dignifiedquiredivagant-martianrklaehn
authored
refactor(iroh): extract docs RPC into iroh-docs (#2868)
Depends on n0-computer/iroh-docs#5 --------- Co-authored-by: Diva M <[email protected]> Co-authored-by: Ruediger Klaehn <[email protected]>
1 parent ba1ffa1 commit 289b4cf

File tree

18 files changed

+91
-3880
lines changed

18 files changed

+91
-3880
lines changed

Cargo.lock

Lines changed: 8 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

iroh-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ human-time = "0.1.6"
4242
indicatif = { version = "0.17", features = ["tokio"] }
4343
iroh = { version = "0.28.1", path = "../iroh", features = ["metrics"] }
4444
iroh-gossip = "0.28.1"
45+
iroh-docs = { version = "0.28.0", features = ["rpc"]}
4546
iroh-metrics = { version = "0.28.0" }
4647
parking_lot = "0.12.1"
4748
pkarr = { version = "2.2.0", default-features = false }

iroh-cli/src/commands/docs.rs

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ use indicatif::{HumanBytes, HumanDuration, MultiProgress, ProgressBar, ProgressS
1818
use iroh::{
1919
base::{base32::fmt_short, node_addr::AddrInfoOptions},
2020
blobs::{provider::AddProgress, util::SetTagOption, Hash, Tag},
21-
client::{
22-
blobs::WrapOption,
23-
docs::{Doc, Entry, LiveEvent, Origin, ShareMode},
24-
Iroh,
25-
},
21+
client::{blobs::WrapOption, Doc, Iroh},
2622
docs::{
2723
store::{DownloadPolicy, FilterKind, Query, SortDirection},
2824
AuthorId, DocTicket, NamespaceId,
2925
},
3026
util::fs::{path_content_info, path_to_key, PathContent},
3127
};
28+
use iroh_docs::{
29+
engine::Origin,
30+
rpc::client::docs::{Entry, LiveEvent, ShareMode},
31+
};
3232
use tokio::io::AsyncReadExt;
3333

3434
use crate::config::ConsoleEnv;
@@ -414,7 +414,7 @@ impl DocCommands {
414414

415415
let mut stream = doc.get_many(query).await?;
416416
while let Some(entry) = stream.try_next().await? {
417-
println!("{}", fmt_entry(&doc, &entry, mode).await);
417+
println!("{}", fmt_entry(&iroh.blobs(), &entry, mode).await);
418418
}
419419
}
420420
Self::Keys {
@@ -440,7 +440,7 @@ impl DocCommands {
440440
query = query.sort_by(sort.into(), direction);
441441
let mut stream = doc.get_many(query).await?;
442442
while let Some(entry) = stream.try_next().await? {
443-
println!("{}", fmt_entry(&doc, &entry, mode).await);
443+
println!("{}", fmt_entry(&iroh.blobs(), &entry, mode).await);
444444
}
445445
}
446446
Self::Leave { doc } => {
@@ -516,7 +516,7 @@ impl DocCommands {
516516
}
517517
Some(e) => e,
518518
};
519-
match entry.content_reader(&doc).await {
519+
match iroh.blobs().read(entry.content_hash()).await {
520520
Ok(mut content) => {
521521
if let Some(dir) = path.parent() {
522522
if let Err(err) = std::fs::create_dir_all(dir) {
@@ -547,13 +547,14 @@ impl DocCommands {
547547
Self::Watch { doc } => {
548548
let doc = get_doc(iroh, env, doc).await?;
549549
let mut stream = doc.subscribe().await?;
550+
let blobs = iroh.blobs();
550551
while let Some(event) = stream.next().await {
551552
let event = event?;
552553
match event {
553554
LiveEvent::InsertLocal { entry } => {
554555
println!(
555556
"local change: {}",
556-
fmt_entry(&doc, &entry, DisplayContentMode::Auto).await
557+
fmt_entry(&blobs, &entry, DisplayContentMode::Auto).await
557558
)
558559
}
559560
LiveEvent::InsertRemote {
@@ -563,17 +564,17 @@ impl DocCommands {
563564
} => {
564565
let content = match content_status {
565566
iroh::docs::ContentStatus::Complete => {
566-
fmt_entry(&doc, &entry, DisplayContentMode::Auto).await
567+
fmt_entry(&blobs, &entry, DisplayContentMode::Auto).await
567568
}
568569
iroh::docs::ContentStatus::Incomplete => {
569570
let (Ok(content) | Err(content)) =
570-
fmt_content(&doc, &entry, DisplayContentMode::ShortHash)
571+
fmt_content(&blobs, &entry, DisplayContentMode::ShortHash)
571572
.await;
572573
format!("<incomplete: {} ({})>", content, human_len(&entry))
573574
}
574575
iroh::docs::ContentStatus::Missing => {
575576
let (Ok(content) | Err(content)) =
576-
fmt_content(&doc, &entry, DisplayContentMode::ShortHash)
577+
fmt_content(&blobs, &entry, DisplayContentMode::ShortHash)
577578
.await;
578579
format!("<missing: {} ({})>", content, human_len(&entry))
579580
}
@@ -679,14 +680,19 @@ impl DocCommands {
679680

680681
/// Gets the document given the client, the environment (and maybe the [`NamespaceID`]).
681682
async fn get_doc(iroh: &Iroh, env: &ConsoleEnv, id: Option<NamespaceId>) -> anyhow::Result<Doc> {
683+
let doc_id = env.doc(id)?;
682684
iroh.docs()
683-
.open(env.doc(id)?)
685+
.open(doc_id)
684686
.await?
685687
.context("Document not found")
686688
}
687689

688690
/// Formats the content. If an error occurs it's returned in a formatted, friendly way.
689-
async fn fmt_content(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> Result<String, String> {
691+
async fn fmt_content(
692+
blobs: &iroh::client::blobs::Client,
693+
entry: &Entry,
694+
mode: DisplayContentMode,
695+
) -> Result<String, String> {
690696
let read_failed = |err: anyhow::Error| format!("<failed to get content: {err}>");
691697
let encode_hex = |err: std::string::FromUtf8Error| format!("0x{}", hex::encode(err.as_bytes()));
692698
let as_utf8 = |buf: Vec<u8>| String::from_utf8(buf).map(|repr| format!("\"{repr}\""));
@@ -695,11 +701,17 @@ async fn fmt_content(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> Resu
695701
DisplayContentMode::Auto => {
696702
if entry.content_len() < MAX_DISPLAY_CONTENT_LEN {
697703
// small content: read fully as UTF-8
698-
let bytes = entry.content_bytes(doc).await.map_err(read_failed)?;
704+
let bytes = blobs
705+
.read_to_bytes(entry.content_hash())
706+
.await
707+
.map_err(read_failed)?;
699708
Ok(as_utf8(bytes.into()).unwrap_or_else(encode_hex))
700709
} else {
701710
// large content: read just the first part as UTF-8
702-
let mut blob_reader = entry.content_reader(doc).await.map_err(read_failed)?;
711+
let mut blob_reader = blobs
712+
.read(entry.content_hash())
713+
.await
714+
.map_err(read_failed)?;
703715
let mut buf = Vec::with_capacity(MAX_DISPLAY_CONTENT_LEN as usize + 5);
704716

705717
blob_reader
@@ -714,7 +726,10 @@ async fn fmt_content(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> Resu
714726
}
715727
DisplayContentMode::Content => {
716728
// read fully as UTF-8
717-
let bytes = entry.content_bytes(doc).await.map_err(read_failed)?;
729+
let bytes = blobs
730+
.read_to_bytes(entry.content_hash())
731+
.await
732+
.map_err(read_failed)?;
718733
Ok(as_utf8(bytes.into()).unwrap_or_else(encode_hex))
719734
}
720735
DisplayContentMode::ShortHash => {
@@ -735,12 +750,16 @@ fn human_len(entry: &Entry) -> HumanBytes {
735750

736751
/// Formats an entry for display as a `String`.
737752
#[must_use = "this won't be printed, you need to print it yourself"]
738-
async fn fmt_entry(doc: &Doc, entry: &Entry, mode: DisplayContentMode) -> String {
753+
async fn fmt_entry(
754+
blobs: &iroh::client::blobs::Client,
755+
entry: &Entry,
756+
mode: DisplayContentMode,
757+
) -> String {
739758
let key = std::str::from_utf8(entry.key())
740759
.unwrap_or("<bad key>")
741760
.bold();
742761
let author = fmt_short(entry.author());
743-
let (Ok(content) | Err(content)) = fmt_content(doc, entry, mode).await;
762+
let (Ok(content) | Err(content)) = fmt_content(blobs, entry, mode).await;
744763
let len = human_len(entry);
745764
format!("@{author}: {key} = {content} ({len})")
746765
}

iroh/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ iroh-router = { version = "0.28.0" }
3636
nested_enum_utils = "0.1.0"
3737
num_cpus = { version = "1.15.0" }
3838
portable-atomic = "1"
39-
iroh-docs = { version = "0.28.0" }
39+
iroh-docs = { version = "0.28.0", features = ["rpc"] }
4040
iroh-gossip = "0.28.1"
4141
parking_lot = "0.12.1"
4242
postcard = { version = "1", default-features = false, features = ["alloc", "use-std", "experimental-derive"] }

iroh/examples/client.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ async fn main() -> anyhow::Result<()> {
1616
// Could also use `node` directly, as it derefs to the client.
1717
let client = node.client();
1818

19+
let blobs = client.blobs();
1920
let doc = client.docs().create().await?;
2021
let author = client.authors().default().await?;
2122

@@ -24,8 +25,7 @@ async fn main() -> anyhow::Result<()> {
2425
let mut stream = doc.get_many(Query::all()).await?;
2526
while let Some(entry) = stream.try_next().await? {
2627
println!("entry {}", fmt_entry(&entry));
27-
// You can pass either `&doc` or the `client`.
28-
let content = entry.content_bytes(&doc).await?;
28+
let content = blobs.read_to_bytes(entry.content_hash()).await?;
2929
println!(" content {}", std::str::from_utf8(&content)?)
3030
}
3131

iroh/src/client.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ pub use crate::rpc_protocol::RpcService;
1414

1515
mod quic;
1616

17-
pub(crate) use self::quic::{connect_raw as quic_connect_raw, RPC_ALPN};
18-
pub use self::{docs::Doc, net::NodeStatus};
19-
20-
pub mod authors;
2117
pub use iroh_blobs::rpc::client::{blobs, tags};
18+
pub use iroh_docs::rpc::client::{authors, docs, docs::Doc};
2219
pub use iroh_gossip::rpc::client as gossip;
23-
pub mod docs;
20+
21+
pub use self::net::NodeStatus;
22+
pub(crate) use self::quic::{connect_raw as quic_connect_raw, RPC_ALPN};
2423
pub mod net;
2524

2625
// Keep this type exposed, otherwise every occurrence of `RpcClient` in the API
@@ -61,13 +60,13 @@ impl Iroh {
6160
}
6261

6362
/// Returns the docs client.
64-
pub fn docs(&self) -> &docs::Client {
65-
docs::Client::ref_cast(&self.rpc)
63+
pub fn docs(&self) -> iroh_docs::rpc::client::docs::Client {
64+
iroh_docs::rpc::client::docs::Client::new(self.rpc.clone().map().boxed())
6665
}
6766

68-
/// Returns the authors client.
69-
pub fn authors(&self) -> &authors::Client {
70-
authors::Client::ref_cast(&self.rpc)
67+
/// Returns the docs client.
68+
pub fn authors(&self) -> iroh_docs::rpc::client::authors::Client {
69+
iroh_docs::rpc::client::authors::Client::new(self.rpc.clone().map().boxed())
7170
}
7271

7372
/// Returns the tags client.

0 commit comments

Comments
 (0)