Skip to content

Instantly share code, notes, and snippets.

@ErnWong
Created May 16, 2021 00:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ErnWong/cc57a1fc9f706f9cebeb9765ced86c9a to your computer and use it in GitHub Desktop.
Save ErnWong/cc57a1fc9f706f9cebeb9765ced86c9a to your computer and use it in GitHub Desktop.
mod borrow_method {
use std::borrow::{Borrow, BorrowMut};
pub struct Inner {
x: i32,
}
impl Inner {
pub fn new() -> Self {
Inner { x: 0 }
}
pub fn some_mut_method(&mut self) {
self.x += 1;
}
pub fn some_method(&self) -> i32 {
self.x + 2
}
pub fn some_reference(&self) -> &i32 {
&self.x
}
}
//pub struct InnerRef<'a>(&'a Inner);
//pub struct InnerRefMut<'a>(&'a mut Inner);
//pub struct InnerRefUniversal<RefType: AsRef<Inner>>(RefType);
pub struct InnerRefUniversal<'a, RefType: InnerBorrow<'a>>(RefType, std::marker::PhantomData<&'a()>);
/*
struct InnerRefInternal<'a>(&'a Inner);
struct InnerRefMutInternal<'a>(&'a mut Inner);
impl<'a> AsRef<Inner> for InnerRefInternal<'a> {
fn as_ref(&self) -> &Inner {
self.0
}
}
impl<'a> AsRef<Inner> for InnerRefMutInternal<'a> {
fn as_ref(&self) -> &Inner {
self.0
}
}
impl<'a> AsMut<Inner> for InnerRefMutInternal<'a> {
fn as_mut(&mut self) -> &mut Inner {
self.0
}
}
*/
/*
impl<'a> AsRef<Inner> for &'a Inner {
fn as_ref(&self) -> &Inner {
self
}
}
impl<'a> AsRef<Inner> for &'a mut Inner {
fn as_ref(&self) -> &Inner {
self
}
}
impl<'a> AsMut<Inner> for &'a mut Inner {
fn as_mut(&mut self) -> &mut Inner {
self
}
}*/
//pub type InnerRef<'a> = InnerRefUniversal<InnerRefInternal<'a>>;
//pub type InnerRefMut<'a> = InnerRefUniversal<InnerRefMutInternal<'a>>;
pub type InnerRef<'a> = InnerRefUniversal<'a, &'a Inner>;
pub type InnerRefMut<'a> = InnerRefUniversal<'a, &'a mut Inner>;
/*
impl<RefType: AsRef<Inner>> InnerRefUniversal<RefType> {
pub fn some_method(&self) -> i32 {
self.0.as_ref().some_method()
}
}
impl<RefType: AsMut<Inner> + AsRef<Inner>> InnerRefUniversal<RefType> {
pub fn some_mut_method(&mut self) {
self.0.as_mut().some_mut_method()
}
}
*/
trait InnerBorrow<'a> {
fn borrow(&self) -> &'a Inner;
}
impl<'a> InnerBorrow<'a> for &'a Inner {
fn borrow(&self) -> &'a Inner {
&*self
}
}
impl<'a> InnerBorrow<'a> for &'a mut Inner {
fn borrow(&self) -> &'a Inner {
&*self
}
}
impl<'a, RefType: InnerBorrow<'a>> InnerRefUniversal<'a, RefType> {
pub fn some_method(&self) -> i32 {
self.0.borrow().some_method()
}
pub fn some_reference(&self) -> &i32 {
self.0.borrow().some_reference()
}
}
impl<'a, RefType: Borrow<Inner> + InnerBorrow<'a>> InnerRefUniversal<'a, RefType> {
pub fn some_mut_method(&mut self) {
self.0.borrow_mut().some_mut_method()
}
}
/*
impl InnerRef<'_> {
pub fn some_method(&self) -> i32 {
self.0.some_method()
}
}
impl InnerRefMut<'_> {
pub fn some_method(&self) -> i32 {
self.0.some_method()
}
pub fn some_mut_method(&mut self) {
self.0.some_mut_method()
}
}*/
pub struct Outer {
inner: Inner,
}
impl Outer {
pub fn new() -> Self {
Outer { inner: Inner::new() }
}
pub fn inner(&self) -> InnerRef {
InnerRefUniversal::<&Inner>(&self.inner)
//InnerRefUniversal(InnerRefInternal(&self.inner))
}
pub fn inner_mut(&mut self) -> InnerRefMut {
InnerRefUniversal::<&mut Inner>(&mut self.inner)
//InnerRefUniversal(InnerRefMutInternal(&mut self.inner))
}
}
}
/*
mod trait_method {
//use std::borrow::{Borrow, BorrowMut};
struct Inner {
x: i32,
}
impl Inner {
pub fn new() -> Self {
Inner { x: 0 }
}
pub fn some_mut_method(&mut self) {
self.x += 1;
}
pub fn some_method(&self) -> i32 {
self.x + 2
}
}
mod private {
use super::Inner;
pub trait Borrowable {
fn borrow(&self) -> &Inner;
}
pub trait BorrowMutable {
fn borrow_mut(&mut self) -> &mut Inner;
}
}
use private::{Borrowable, BorrowMutable};
pub trait InnerRefable: Borrowable {
fn some_method(&self) {
self.borrow().some_method();
}
}
pub trait InnerRefMutable: BorrowMutable {
fn some_mut_method(&mut self) {
self.borrow_mut().some_mut_method();
}
}
pub struct InnerRef<'a>(&'a Inner);
pub struct InnerRefMut<'a>(&'a mut Inner);
impl Borrowable for InnerRef<'_> {
fn borrow(&self) -> &Inner { self.0 }
}
impl Borrowable for InnerRefMut<'_> {
fn borrow(&self) -> &Inner { self.0 }
}
impl BorrowMutable for InnerRefMut<'_> {
fn borrow_mut(&mut self) -> &mut Inner { self.0 }
}
impl InnerRefable for InnerRef<'_> {}
impl InnerRefable for InnerRefMut<'_> {}
impl InnerRefMutable for InnerRefMut<'_> {}
pub struct Outer {
inner: Inner,
}
impl Outer {
pub fn new() -> Self {
Outer { inner: Inner::new() }
}
pub fn inner(&self) -> InnerRef {
InnerRef(&self.inner)
//InnerRefUniversal(InnerRefInternal(&self.inner))
}
pub fn inner_mut(&mut self) -> InnerRefMut {
InnerRefMut(&mut self.inner)
//InnerRefUniversal(InnerRefMutInternal(&mut self.inner))
}
}
}
*/
fn main() {
{
let mut outer = borrow_method::Outer::new();
outer.inner().some_method();
outer.inner_mut().some_method();
outer.inner_mut().some_mut_method();
let x = {
let inner = outer.inner();
inner.some_reference()
};
println!("{}", x);
}
/*{
use trait_method::InnerRefable;
use trait_method::InnerRefMutable;
let mut outer = trait_method::Outer::new();
outer.inner().some_method();
outer.inner_mut().some_method();
outer.inner_mut().some_mut_method();
}*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment