-
-
Save rust-play/0a5bbc9d094fa14eb7852c5832b07677 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Consider `main` to be user code. | |
fn main() { | |
use crate::lib::{send_command, Connection}; | |
/// Users can define their own types and `impl Connection` for them. | |
struct NewType(i32); | |
impl Connection for NewType {} | |
let x = NewType(0); | |
send_command(x); | |
} | |
/// Consider `lib` to be your public library interface. | |
mod lib { | |
use self::inner::PrivateConnection; | |
/// The linter knows we're doing questionable things with visibility here, | |
/// but I believe this is an acceptable use case as outlined at: | |
/// https://rust-lang.github.io/rfcs/2145-type-privacy.html#lint-2-private-traitstypes-in-secondary-interface-of-effectively-public-items | |
/// | |
/// By putting `really_complicated_send` into a supertrait, we can offer more fine grained visibility | |
/// while still ensuring all things which `impl Connection` can still use it (within the library). | |
#[allow(private_bounds)] | |
pub trait Connection: PrivateConnection {} | |
pub fn send_command(connection: impl Connection) { | |
connection.really_complicated_send(); | |
} | |
/// Consider `inner` to be a private module within your library. | |
/// | |
/// This is the sealed trait pattern: | |
/// https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed | |
/// | |
/// In this case we're using it for the `PrivateConnection` supertrait, to keep `really_complicated_send` visible | |
/// and usable for all things which `impl Connection` within the library, but invisible (and thus unusable) to | |
/// downstream implementors of `Connection`. | |
mod inner { | |
use super::Connection; | |
pub(super) trait PrivateConnection { | |
fn really_complicated_send(&self); | |
} | |
impl<T: Connection> PrivateConnection for T { | |
fn really_complicated_send(&self) { | |
println!("Performing a really complicated send!"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment