refactor(lib): keep the actors inside the crate and mark the growing enums
Every release since 14 has been a major, because the actor mailboxes, the share index's struct and the CLI's command enum were all exhaustive public API: adding a peer message, a scanned field or a subcommand read as a breaking change to the library. The actors, dispatcher, peer plumbing and download store are how the client is built, not what a host programs against, so they move inside the crate; PeerMessage, SharedFile and the CLI command enums are non-exhaustive; ConnectionType is re-exported at the root for the one thing hosts used it for. A one-time break so that the next additions are not.
This commit is contained in:
@@ -52,7 +52,7 @@ impl<M: Send> ActorHandle<M> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Internal actor message wrapper
|
/// Internal actor message wrapper
|
||||||
pub(crate) enum ActorMessage<M> {
|
pub enum ActorMessage<M> {
|
||||||
UserMessage(M),
|
UserMessage(M),
|
||||||
Stop,
|
Stop,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ use std::sync::mpsc::{Receiver, Sender};
|
|||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
/// Marked non-exhaustive: each peer message the client learns adds a variant.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum PeerMessage {
|
pub enum PeerMessage {
|
||||||
SendMessage(Message),
|
SendMessage(Message),
|
||||||
FileSearchResult(SearchResult),
|
FileSearchResult(SearchResult),
|
||||||
|
|||||||
@@ -2,14 +2,17 @@
|
|||||||
// example in it, so a signature change cannot leave the advertised usage stale.
|
// example in it, so a signature change cannot leave the advertised usage stale.
|
||||||
#![doc = include_str!("../README.md")]
|
#![doc = include_str!("../README.md")]
|
||||||
|
|
||||||
// Core modules
|
// The public surface is the client, its types, the wire codec and the share
|
||||||
pub mod actor;
|
// index. The actors, dispatcher, peer plumbing and download store are how the
|
||||||
|
// client is built, not what a host programs against, so they stay inside the
|
||||||
|
// crate and a change to them is not a change to the library's API.
|
||||||
|
pub(crate) mod actor;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod dispatcher;
|
pub(crate) mod dispatcher;
|
||||||
pub mod download_store;
|
pub(crate) mod download_store;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod message;
|
pub mod message;
|
||||||
pub mod peer;
|
pub(crate) mod peer;
|
||||||
pub mod shares;
|
pub mod shares;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@@ -31,6 +34,7 @@ pub use actor::server_actor::{PeerAddress, UserMessage};
|
|||||||
pub use client::{Client, ClientSettings};
|
pub use client::{Client, ClientSettings};
|
||||||
pub use error::{Result, SoulseekRs};
|
pub use error::{Result, SoulseekRs};
|
||||||
pub use message::peer::{SharedDirectory, SharedFileEntry};
|
pub use message::peer::{SharedDirectory, SharedFileEntry};
|
||||||
|
pub use peer::ConnectionType;
|
||||||
pub use types::{
|
pub use types::{
|
||||||
ClientVersion, DownloadStatus, File, RoomEvent, RoomInfo, Search,
|
ClientVersion, DownloadStatus, File, RoomEvent, RoomInfo, Search,
|
||||||
SearchResult, SessionLoss, Transfer, UploadInfo, UploadStatus, UserInfo,
|
SearchResult, SessionLoss, Transfer, UploadInfo, UploadStatus, UserInfo,
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ pub mod listen;
|
|||||||
pub mod upload_peer;
|
pub mod upload_peer;
|
||||||
|
|
||||||
// Export actor types
|
// Export actor types
|
||||||
pub use crate::actor::peer_actor::{PeerActor, PeerMessage};
|
pub use crate::actor::peer_actor::PeerMessage;
|
||||||
pub use crate::actor::peer_registry::PeerRegistry;
|
|
||||||
|
|
||||||
pub(crate) use download_peer::part_path_of;
|
pub use download_peer::part_path_of;
|
||||||
pub use download_peer::{DownloadError, DownloadPeer};
|
pub use download_peer::{DownloadError, DownloadPeer};
|
||||||
|
|
||||||
use crate::message::Message;
|
use crate::message::Message;
|
||||||
|
|||||||
@@ -12,7 +12,11 @@ use std::io;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
/// One shared file: its peer-facing virtual path and where it lives on disk.
|
/// One shared file: its peer-facing virtual path and where it lives on disk.
|
||||||
|
///
|
||||||
|
/// Built by the scan, never by a host, so fields can be added without a
|
||||||
|
/// breaking release.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct SharedFile {
|
pub struct SharedFile {
|
||||||
/// Backslash-separated path exposed to peers, e.g. `music\album\song.mp3`.
|
/// Backslash-separated path exposed to peers, e.g. `music\album\song.mp3`.
|
||||||
pub virtual_path: String,
|
pub virtual_path: String,
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ use std::time::{Duration, Instant};
|
|||||||
|
|
||||||
use soulseek_rs::message::Message;
|
use soulseek_rs::message::Message;
|
||||||
use soulseek_rs::message::server::MessageFactory;
|
use soulseek_rs::message::server::MessageFactory;
|
||||||
use soulseek_rs::peer::ConnectionType;
|
|
||||||
use soulseek_rs::{
|
use soulseek_rs::{
|
||||||
Client, ClientSettings, ClientVersion, DownloadStatus, PeerAddress,
|
Client, ClientSettings, ClientVersion, ConnectionType, DownloadStatus,
|
||||||
SessionLoss, UploadStatus,
|
PeerAddress, SessionLoss, UploadStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Only one test at a time may drive a server.
|
/// Only one test at a time may drive a server.
|
||||||
|
|||||||
@@ -172,7 +172,11 @@ pub struct Cli {
|
|||||||
pub log_file: Option<PathBuf>,
|
pub log_file: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Non-exhaustive: this enum is public through the crate's library target so
|
||||||
|
/// the integration tests can reach it, and a new subcommand must not read as a
|
||||||
|
/// breaking change of that library.
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
/// Search the network and print matching files
|
/// Search the network and print matching files
|
||||||
Search(SearchArgs),
|
Search(SearchArgs),
|
||||||
@@ -254,6 +258,7 @@ pub struct DaemonArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum DaemonCommand {
|
pub enum DaemonCommand {
|
||||||
/// Print the token remote clients authenticate with
|
/// Print the token remote clients authenticate with
|
||||||
Token,
|
Token,
|
||||||
@@ -266,6 +271,7 @@ pub enum DaemonCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
|
#[non_exhaustive]
|
||||||
pub enum CompletionsCommand {
|
pub enum CompletionsCommand {
|
||||||
/// Write the completion script where the shell looks for it
|
/// Write the completion script where the shell looks for it
|
||||||
Install(CompletionsArgs),
|
Install(CompletionsArgs),
|
||||||
|
|||||||
Reference in New Issue
Block a user