Skip to content

refactor: Refactor folder structure#81

Merged
artrixdotdev merged 2 commits intomainfrom
refactor/folder-structure
Aug 2, 2025
Merged

refactor: Refactor folder structure#81
artrixdotdev merged 2 commits intomainfrom
refactor/folder-structure

Conversation

@artrixdotdev
Copy link
Owner

@artrixdotdev artrixdotdev commented Aug 2, 2025

An attempt to reorganize the project and avoid the usage of nested folders. I will also be tackling #40 in this PR

Summary by CodeRabbit

  • New Features

    • Introduced a new Peer struct with related methods and trait implementations for managing BitTorrent peers.
    • Added support for peer connection handling and message exchange in the protocol layer.
  • Refactor

    • Reorganized internal modules and updated import paths for improved clarity and maintainability.
    • Consolidated and simplified module structure, replacing previous modules with new metainfo, peer, and protocol modules.
  • Chores

    • Removed obsolete modules and code related to the old peer management implementation.
    • Updated references throughout the codebase to align with the new module organization.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 2, 2025

Walkthrough

This change reorganizes the internal module structure of the libtortillas crate by moving peer-related code from the peers module into new modules: peer (for the Peer struct and related types) and protocol (for peer communication logic). Imports throughout the crate are updated to reflect this new structure. The Peer struct and its methods, previously in peers, are now in peer and protocol. No major logic changes occur outside this reorganization.

Changes

Cohort / File(s) Change Summary
Module Structure Reorganization
crates/libtortillas/src/lib.rs, crates/libtortillas/src/peers/mod.rs, crates/libtortillas/src/peers/peer/mod.rs, crates/libtortillas/src/peer/mod.rs, crates/libtortillas/src/protocol/mod.rs
- Removed the parser and peers modules.
- Added new public modules: metainfo, peer, and protocol.
- Deleted the old peers/mod.rs (which contained the Peer struct and connection logic) and its submodule declarations.
- Added a new peer/mod.rs defining the Peer struct, related types, and trait implementations.
- Moved the peer connection handler (handle_peer) and related logic to protocol/mod.rs.
- Updated module declarations and structure accordingly.
Peer-Related Imports Update
crates/libtortillas/src/engine/mod.rs, crates/libtortillas/src/metainfo/file.rs, crates/libtortillas/src/metainfo/magnet.rs, crates/libtortillas/src/peer/id.rs, crates/libtortillas/src/peer/info.rs, crates/libtortillas/src/peer/state.rs, crates/libtortillas/src/peer/supports.rs, crates/libtortillas/src/protocol/commands.rs, crates/libtortillas/src/protocol/messages.rs, crates/libtortillas/src/protocol/stream.rs, crates/libtortillas/src/tracker/http.rs, crates/libtortillas/src/tracker/mod.rs, crates/libtortillas/src/tracker/udp.rs
- Updated import paths from peers::* or parser::* to peer::* or metainfo::* as appropriate.
- Adjusted references to Peer, PeerId, MetaInfo, MAGIC_STRING, etc., to match the new module structure.
- No logic or control flow changes.
PeerId Conversion Optimization
crates/libtortillas/src/peer/id.rs
- Simplified the conversion from Hash<20> to PeerId by removing an unnecessary clone, directly dereferencing the hash's byte slice.
Peer Connection Handler Relocation and Update
crates/libtortillas/src/protocol/mod.rs
- Added the handle_peer asynchronous method to the Peer struct in the protocol module.
- This method manages peer connection lifecycle, message exchanges, and communication with the torrent engine.
- Introduced a helper function for sending messages to the engine.
- Incorporated imports and type aliases to support these operations.
- The method was moved from the old peers module and adapted to the new structure.

Sequence Diagram(s)

sequenceDiagram
    participant Engine
    participant Peer
    participant Protocol
    participant Network

    Engine->>Peer: Create Peer (with addr, id, etc.)
    Peer->>Protocol: handle_peer(...)
    Protocol->>Network: Establish connection (handshake)
    Network-->>Protocol: Connection established
    Protocol->>Peer: Update state (choke, interested, etc.)
    Protocol->>Engine: Send PeerResponse via channel
    Engine-->>Protocol: Send PeerCommand via channel
    Protocol->>Network: Send/receive messages (bitfield, requests, etc.)
    Note over Protocol,Network: Loop: select! over peer, engine, and internal messages
    Protocol-->>Engine: Notify on errors or completion
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • artrixdotdev/tortillas#80: Adds detailed peer ID parsing and serialization in peer::id and updates usages, which intersects with this PR's relocation and refactoring of peer-related modules and types.
  • artrixdotdev/tortillas#41: Refactors transport and peer abstractions, introducing new methods and constructors for the Peer struct, which are also affected by the module restructuring in this PR.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ 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/folder-structure

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.
    • Explain this complex logic.
    • 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. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • 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 src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

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

Documentation and Community

  • 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.

@artrixdotdev artrixdotdev marked this pull request as ready for review August 2, 2025 20:43
Copy link
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

🔭 Outside diff range comments (3)
crates/libtortillas/src/metainfo/magnet.rs (1)

51-57: Gracefully handle malformed magnet URIs

next_back().unwrap() will panic if the string has no ?, e.g. an already-split query or user-supplied bad input. Bubble an error instead:

-      let qs = uri.split('?').next_back().unwrap();
+      let qs = uri
+          .split('?')
+          .next_back()
+          .ok_or_else(|| anyhow::anyhow!("Magnet URI missing `?` delimiter"))?;
crates/libtortillas/src/peer/info.rs (1)

56-63: Replace panics with proper error handling

unwrap() and assert_eq! will crash the process on malformed metadata or hash mismatch. Return an error instead:

-      let info_dict: Info = serde_bencode::from_bytes(&self.info_bytes).unwrap();
-
-      // Validate hash of struct with given info hash
-      assert_eq!(
-         real_info_hash, info_hash,
-         "Inputted info_hash was not the same as generated info_hash"
-      );
+      let info_dict: Info = serde_bencode::from_bytes(&self.info_bytes)
+          .map_err(|e| anyhow::anyhow!("Failed to parse info dict: {e}"))?;
+
+      if real_info_hash != info_hash {
+          bail!("Inputted info_hash does not match hash of metadata bytes");
+      }

You’ll need to add use anyhow::anyhow; at the top.

crates/libtortillas/src/protocol/mod.rs (1)

564-564: Fix incorrect trace message

The trace message states "Peer does not support BEP 0009 or BEP 0010" but it's outside the if condition, so it will always print even when the peer does support these extensions.

Apply this diff to fix the logic:

-            trace!("Peer does not support BEP 0009 or BEP 0010");
+            } else {
+                trace!(%peer_addr, "Peer does not support BEP 0009 or BEP 0010");
+            }
🧹 Nitpick comments (3)
crates/libtortillas/src/metainfo/file.rs (1)

10-13: Minor style nit – prefer a relative path here

Inside the metainfo module you can shorten the import:

use super::MetaInfo;

This avoids an unnecessary hard-coded crate path and reduces churn if the module gets renamed again.

crates/libtortillas/src/metainfo/magnet.rs (1)

5-9: Same style nit as in file.rs

Consider the relative import:

use super::MetaInfo;

Keeps the codebase consistent.

crates/libtortillas/src/protocol/mod.rs (1)

54-250: Consider breaking down the large handle_peer method

The handle_peer method spans nearly 200 lines and handles multiple responsibilities. Consider extracting some of the logic into smaller helper methods for better maintainability:

  • Connection setup logic (lines 71-94)
  • Initial message sending logic (lines 109-148)
  • Message handling loop setup (lines 171-174)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b260626 and 7617ab0.

📒 Files selected for processing (18)
  • crates/libtortillas/src/engine/mod.rs (2 hunks)
  • crates/libtortillas/src/lib.rs (1 hunks)
  • crates/libtortillas/src/metainfo/file.rs (1 hunks)
  • crates/libtortillas/src/metainfo/magnet.rs (1 hunks)
  • crates/libtortillas/src/peer/id.rs (1 hunks)
  • crates/libtortillas/src/peer/info.rs (1 hunks)
  • crates/libtortillas/src/peer/mod.rs (1 hunks)
  • crates/libtortillas/src/peer/state.rs (1 hunks)
  • crates/libtortillas/src/peer/supports.rs (1 hunks)
  • crates/libtortillas/src/peers/mod.rs (0 hunks)
  • crates/libtortillas/src/peers/peer/mod.rs (0 hunks)
  • crates/libtortillas/src/protocol/commands.rs (1 hunks)
  • crates/libtortillas/src/protocol/messages.rs (1 hunks)
  • crates/libtortillas/src/protocol/mod.rs (1 hunks)
  • crates/libtortillas/src/protocol/stream.rs (1 hunks)
  • crates/libtortillas/src/tracker/http.rs (2 hunks)
  • crates/libtortillas/src/tracker/mod.rs (1 hunks)
  • crates/libtortillas/src/tracker/udp.rs (2 hunks)
💤 Files with no reviewable changes (2)
  • crates/libtortillas/src/peers/peer/mod.rs
  • crates/libtortillas/src/peers/mod.rs
🧰 Additional context used
🧬 Code Graph Analysis (3)
crates/libtortillas/src/tracker/mod.rs (2)
crates/libtortillas/src/peers/mod.rs (6)
  • peer (29-29)
  • PeerKey (35-35)
  • PeerId (36-36)
  • peer_comms (30-30)
  • Peer (43-54)
  • tests (342-535)
crates/libtortillas/src/peers/peer/mod.rs (1)
  • info (1-1)
crates/libtortillas/src/metainfo/magnet.rs (1)
crates/libtortillas/src/parser/mod.rs (4)
  • file (2-2)
  • MetaInfo (12-15)
  • magnet (3-3)
  • tests (52-127)
crates/libtortillas/src/peer/info.rs (3)
crates/libtortillas/src/parser/file.rs (1)
  • Info (60-87)
crates/libtortillas/src/peers/peer/mod.rs (1)
  • info (1-1)
crates/libtortillas/src/parser/mod.rs (3)
  • magnet (3-3)
  • file (2-2)
  • MetaInfo (12-15)
🔇 Additional comments (20)
crates/libtortillas/src/tracker/mod.rs (1)

14-17: Import path update looks correct

The move from peers::{Peer, PeerId} to peer::{Peer, PeerId} matches the new module layout and should compile provided pub mod peer is re-exported at the crate root.
No further action needed.

crates/libtortillas/src/protocol/messages.rs (1)

14-18: Import change ACK

MAGIC_STRING and PeerId now live under peer; import update is correct and keeps this file compiling.

crates/libtortillas/src/peer/info.rs (1)

4-4: Import path updated – OK

The switch to metainfo::Info reflects the module move. Looks good.

crates/libtortillas/src/protocol/stream.rs (1)

22-24: No stale crate::peers:: imports detected

The rg -n "crate::peers::" command returned no matches, confirming all import paths have been updated to use peer::{…}.

crates/libtortillas/src/peer/supports.rs (1)

8-8: Correct relative import after relocation

Changing to super::Peer correctly follows the new module hierarchy.

crates/libtortillas/src/tracker/udp.rs (2)

28-28: Import fix aligns with peer module rename

PeerId now lives under crate::peer; the updated path is accurate.


985-985: Test import updated to metainfo module – OK

The test now compiles against crate::metainfo::{MagnetUri, MetaInfo} following the parser split.

crates/libtortillas/src/peer/state.rs (1)

11-11: Relative import is correct after peer re-organisation

super::Peer resolves inside the new peer module. No further action needed.

crates/libtortillas/src/peer/id.rs (1)

403-403: Eliminated unnecessary clone – tiny perf gain

Replacing the clone with *hash.as_bytes() avoids an extra allocation and is functionally identical.

crates/libtortillas/src/tracker/http.rs (1)

24-24: Import paths correctly updated

The import path changes from peers::PeerId to peer::PeerId and from parser::{MetaInfo, TorrentFile} to metainfo::{MetaInfo, TorrentFile} are consistent with the module restructuring.

Also applies to: 509-509

crates/libtortillas/src/protocol/commands.rs (1)

3-3: Import consolidation looks good

Consolidating imports from super improves code organization and is consistent with the new module structure where peer communication types are now in the protocol module.

crates/libtortillas/src/engine/mod.rs (1)

20-26: Import paths comprehensively updated

All import paths have been correctly updated to reflect the new module structure:

  • parsermetainfo
  • peerspeer
  • Peer communication modules moved to protocol

The updates are consistent throughout the file, including test imports.

Also applies to: 614-614

crates/libtortillas/src/lib.rs (1)

4-6: Module restructuring correctly implemented

The module declarations properly reflect the folder structure refactoring:

  • parsermetainfo (better describes the module's purpose)
  • peers → split into peer (core types) and protocol (communication logic)

This separation of concerns improves the module organization.

crates/libtortillas/src/protocol/mod.rs (1)

1-32: Protocol module structure looks good

The extraction of peer protocol handling into a dedicated module improves separation of concerns. The imports and type definitions are properly organized.

crates/libtortillas/src/peer/mod.rs (6)

1-4: Good module organization for peer-related functionality.

The separation of peer concerns into distinct modules (id, info, state, supports) promotes maintainability and follows Rust conventions.


6-16: Well-organized imports and re-exports.

The import structure is clean and the re-exports provide a convenient API by making submodule contents available at the parent level. The InternalHash alias helps avoid potential naming conflicts.


17-22: Appropriate type definitions with good documentation.

The PeerKey type alias provides semantic clarity, and the deprecation note shows good maintainer communication. The MAGIC_STRING constant correctly represents the BitTorrent protocol identifier.


24-38: Comprehensive and well-designed Peer struct.

The struct includes all essential fields for BitTorrent peer management: networking, state, piece tracking, protocol extensions, and metadata. The Clone derive and clear documentation enhance usability.


40-70: Excellent trait implementations with consistent identity semantics.

The trait implementations are well-designed and consistent:

  • Debug provides relevant debugging information without overwhelming detail
  • Hash, Eq, and PartialEq consistently use socket address for identity, ensuring correct behavior in collections
  • Display offers a clean, readable format

The consistency across identity-based traits is crucial for correctness.


72-106: Well-designed constructor methods with good API ergonomics.

The constructor methods provide multiple convenient ways to create peers:

  • Sensible defaults in new() (empty pieces, no extensions, clean state)
  • IP version-specific constructors for better ergonomics
  • Natural conversion from SocketAddr
  • Useful socket_addr() getter for networking operations

All methods follow Rust conventions and provide a clean API.

// Is this the best practice? Eh. But realistically, if a peer sends us
// something that is simply invalid, we probably don't want to work with them
// anymore.
panic!("Error occured when receiving a message from the peer");
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid using panic! for error handling

Using panic! when receiving an invalid message from a peer is too aggressive and could crash the application. Consider gracefully disconnecting from the peer instead.

Apply this diff to handle the error gracefully:

-                     // Is this the best practice? Eh. But realistically, if a peer sends us
-                     // something that is simply invalid, we probably don't want to work with them
-                     // anymore.
-                     panic!("Error occured when receiving a message from the peer");
+                     // Disconnect from the peer gracefully
+                     warn!(%peer_addr, "Disconnecting from peer due to invalid message");
+                     break;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
panic!("Error occured when receiving a message from the peer");
// Disconnect from the peer gracefully
warn!(%peer_addr, "Disconnecting from peer due to invalid message");
break;
🤖 Prompt for AI Agents
In crates/libtortillas/src/protocol/mod.rs at line 225, replace the panic! call
used for error handling when receiving a message from a peer with a graceful
disconnection mechanism. Instead of panicking, implement logic to close the
connection or notify the peer of the error, ensuring the application continues
running without crashing.

@artrixdotdev artrixdotdev linked an issue Aug 2, 2025 that may be closed by this pull request
@artrixdotdev artrixdotdev merged commit df895a7 into main Aug 2, 2025
3 checks passed
@artrixdotdev artrixdotdev deleted the refactor/folder-structure branch August 2, 2025 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore: Add more explicit publicity in enums and structs

1 participant