Skip to content

refactor: Changed visiblity of Torrent and related funcs#106

Merged
kurealnum merged 1 commit into
mainfrom
refactor/change-visibility-of-torrent
Aug 19, 2025
Merged

refactor: Changed visiblity of Torrent and related funcs#106
kurealnum merged 1 commit into
mainfrom
refactor/change-visibility-of-torrent

Conversation

@kurealnum
Copy link
Copy Markdown
Collaborator

@kurealnum kurealnum commented Aug 19, 2025

Single commit PR -- see #104

Summary by CodeRabbit

  • New Features
    • The torrent type is now exposed in the public API.
    • Clients can retrieve a torrent’s metadata/details via a public accessor.
    • Clients can obtain a torrent’s info hash directly through the public API.
    • Enables easier integration and inspection of torrent data from outside the library.
    • Additive change with no breaking behavior for existing users.

@kurealnum kurealnum added this to the Engine implementation milestone Aug 19, 2025
@kurealnum kurealnum self-assigned this Aug 19, 2025
@kurealnum kurealnum added low prio Low priority issue refactor Neither fixes a bug nor adds a feature labels Aug 19, 2025
@kurealnum kurealnum linked an issue Aug 19, 2025 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 19, 2025

Walkthrough

Publicly exposed the Torrent type and two of its accessors by changing their visibility from crate-private to public in crates/libtortillas/src/torrent/mod.rs.

Changes

Cohort / File(s) Summary
Public API exposure
crates/libtortillas/src/torrent/mod.rs
Changed Torrent from pub(crate) to pub. Made info_dict(&self) -> Option<&Info> and info_hash(&self) -> InfoHash public methods.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

Suggested labels

enhancement, med prio

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/change-visibility-of-torrent

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot added enhancement New feature or request med prio Medium Priority labels Aug 19, 2025
@kurealnum kurealnum merged commit de852f1 into main Aug 19, 2025
3 checks passed
@kurealnum kurealnum deleted the refactor/change-visibility-of-torrent branch August 19, 2025 18:08
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
crates/libtortillas/src/torrent/mod.rs (3)

57-66: Public info_dict looks good; consider an idiomatic simplification and brief docs

The borrowed return type avoids cloning and is a good choice. Minor clean-up:

  • Use as_ref().or_else(...) to simplify the control flow.
  • Add a short rustdoc comment since this is now part of the public API.

Apply this diff:

-   pub fn info_dict(&self) -> Option<&Info> {
-      if let Some(info) = &self.info {
-         Some(info)
-      } else {
-         match &self.metainfo {
-            MetaInfo::Torrent(t) => Some(&t.info),
-            _ => None,
-         }
-      }
-   }
+   /// Returns a read-only view of the info dictionary if known.
+   ///
+   /// - For .torrent-based MetaInfo: always `Some(&Info)`.
+   /// - For magnet URIs: `Some(&Info)` only after `InfoBytes` have been received; otherwise `None`.
+   pub fn info_dict(&self) -> Option<&Info> {
+      self.info.as_ref().or_else(|| match &self.metainfo {
+         MetaInfo::Torrent(t) => Some(&t.info),
+         _ => None,
+      })
+   }

68-79: Avoid panics in public API; also simplify the else branch

Now that this method is public, the expect(...) panics leak across the crate boundary. Consider returning Option<InfoHash> or Result<InfoHash, TorrentError> (or providing a non-panicking companion like try_info_hash) to keep the library resilient.

Also, you can lean on MetaInfo::info_hash() in the else branch and remove the extra & in if let:

Apply this diff:

-   pub fn info_hash(&self) -> InfoHash {
-      if let Some(info) = &self.info_dict() {
-         info.hash().expect("Failed to compute info hash")
-      } else {
-         match &self.metainfo {
-            MetaInfo::Torrent(t) => t.info.hash().expect("Failed to compute info hash"),
-            MetaInfo::MagnetUri(m) => m
-               .info_hash()
-               .expect("Magnet URIs should always have info hashes"),
-         }
-      }
-   }
+   pub fn info_hash(&self) -> InfoHash {
+      if let Some(info) = self.info_dict() {
+         info.hash().expect("Failed to compute info hash")
+      } else {
+         self.metainfo
+            .info_hash()
+            .expect("Magnet URIs should always have info hashes")
+      }
+   }

Optionally, add a non-panicking companion:

// Place anywhere within `impl Torrent`
pub fn try_info_hash(&self) -> Option<InfoHash> {
   if let Some(info) = self.info_dict() {
      info.hash()
   } else {
      self.metainfo.info_hash()
   }
}

186-213: Expose actor messages or wrap them in a public API

TorrentRequest and TorrentResponse are still pub(crate), so external crates cannot construct messages or call ask(...) directly. Since both Peer and Tracker are declared pub, there’s no private-type-in-public-interface issue—however, the actor API remains inaccessible outside this crate.

Consider one of the following approaches:

  • Make TorrentRequest and TorrentResponse pub, and ensure all their variant payload types (Bitfield, CurrentPeers, PeerCount, CurrentTrackers, InfoHash, HasInfoDict, Request) are public and reachable.
  • Keep the messages private and provide a public façade (e.g., a TorrentClient handle with typed async methods that wrap ask(...) internally).

File: crates/libtortillas/src/torrent/mod.rs (lines 186–213)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 778bb29 and 6556d0b.

📒 Files selected for processing (1)
  • crates/libtortillas/src/torrent/mod.rs (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
crates/libtortillas/src/torrent/mod.rs (2)
crates/libtortillas/src/metainfo/file.rs (2)
  • Info (60-90)
  • TorrentFile (17-32)
crates/libtortillas/src/metainfo/mod.rs (1)
  • test_info_hash_with_torrent (77-88)

};

pub(crate) struct Torrent {
pub struct Torrent {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Making Torrent public: ensure external reachability and intended external usability

  • Public type with private fields is fine and non-breaking for internal invariants.
  • If the intent is for external crates to use this actor, keep in mind that TorrentRequest/TorrentResponse (Lines 188-213) are still pub(crate), which makes the actor effectively crate-internal for messaging. Consider the API story here (see separate comment below).
  • Since new public surface was added, this warrants at least a minor version bump.
  • Verify that all types appearing in now-public method signatures are publicly reachable from the crate root (e.g., metainfo::Info, hashes::InfoHash) to avoid “private type in public interface” errors.

Run this script to confirm the relevant modules/types are exported from the crate root(s):


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching crate roots for public module or re-exports of torrent, hashes, and metainfo…"
fd -t f -a 'lib.rs' | while read -r f; do
  echo
  echo "== $f"
  rg -nP '^\s*pub\s+mod\s+(torrent|hashes|metainfo)\b|^\s*pub\s+use\s+.*\b(torrent|hashes|metainfo)\b' "$f" || true
done

echo
echo "Checking public visibility of InfoHash and Info definitions…"
rg -nP '^\s*pub\s+struct\s+InfoHash\b|^\s*pub\s+struct\s+Info\b'

Length of output: 849


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for all occurrences of InfoHash..."
rg -n 'InfoHash' || true

echo
echo "Checking struct definition and visibility for InfoHash..."
rg -nP '^\s*(pub|pub\(.+\))\s+struct\s+InfoHash\b' -C2 || true

echo
echo "Locating TorrentRequest and TorrentResponse definitions with visibility..."
rg -nP '^\s*(pub|pub\(.+\))\s+struct\s+Torrent(Request|Response)\b' -C3 crates/libtortillas/src/torrent

Length of output: 3877


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Inspecting metainfo module exports in metainfo/mod.rs…"
rg -nP 'mod\s+file\b|pub\s+use\s+file::Info\b' -C2 crates/libtortillas/src/metainfo/mod.rs || true

echo
echo "Locating TorrentRequest and TorrentResponse definitions in torrent/mod.rs…"
rg -nP '^(pub|pub\(.+\))?\s*(enum|struct|type)\s+Torrent(Request|Response)\b' -C5 crates/libtortillas/src/torrent/mod.rs || true

Length of output: 583


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locating TorrentRequest and TorrentResponse definitions and their visibility…"
rg -n 'enum TorrentRequest|enum TorrentResponse' -C3 crates/libtortillas/src/torrent/mod.rs || true

echo
echo "Filtering for pub or pub(crate) qualifiers on those definitions…"
rg -nP '^\s*(pub(?:\([^)]*\))?)\s+enum\s+Torrent(Request|Response)\b' -C2 crates/libtortillas/src/torrent/mod.rs || true

echo
echo "Detecting any public methods on Torrent that reference metainfo::Info…"
rg -nP '^\s*pub\s+fn\b.*\bInfo\b' -C1 crates/libtortillas/src/torrent/mod.rs || true

Length of output: 901


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching for TorrentRequest definitions..."
rg -n 'TorrentRequest' -C3 crates/libtortillas/src || echo "TorrentRequest not found"

echo
echo "Searching for TorrentResponse definitions..."
rg -n 'TorrentResponse' -C3 crates/libtortillas/src || echo "TorrentResponse not found"

Length of output: 15041


Public API inconsistencies: Info not exposed & messaging types still private

  • The torrent, hashes, and metainfo modules are correctly exported in src/lib.rs.
  • hashes::InfoHash is publicly reachable (pub type InfoHash = Hash<20> in src/hashes.rs).
  • Issue: metainfo::Info lives in a private file.rs and is not re-exported, yet
    pub fn info_dict(&self) -> Option<&Info> (in crates/libtortillas/src/torrent/mod.rs:56–58) returns it.
    → Fix by exposing Info, e.g. in crates/libtortillas/src/metainfo/mod.rs add:
    mod file;
    +pub use file::Info;
    mod magnet;
  • Messaging enums TorrentRequest/TorrentResponse (lines 188–189 in crates/libtortillas/src/torrent/mod.rs) remain pub(crate), so external code cannot interact with the Torrent actor. If you intend external messaging, change these to pub.
  • You’ve increased the crate’s public surface—bump at least the minor version.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In crates/libtortillas/src/torrent/mod.rs around line 28 and referencing lines
~56–58 and ~188–189: the public API is inconsistent because Torrent::info_dict()
returns a type Info that is defined privately in metainfo/file.rs and the
messaging enums TorrentRequest/TorrentResponse are pub(crate) so external
callers cannot use the Torrent actor. Fix by re-exporting Info from the metainfo
module (add a pub use in crates/libtortillas/src/metainfo/mod.rs so Info becomes
part of the crate public API), change the visibility of TorrentRequest and
TorrentResponse from pub(crate) to pub if external messaging is intended, and
update the crate version (bump the minor) since the public surface has expanded.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request low prio Low priority issue med prio Medium Priority refactor Neither fixes a bug nor adds a feature

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Increase global visibility of Torrent struct for light user access

1 participant