Created
May 16, 2021 00:27
-
-
Save ErnWong/cc57a1fc9f706f9cebeb9765ced86c9a to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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