use crate::__internal::{Private, SealedInternal};
use std::fmt::Debug;
pub trait Proxied: SealedInternal + AsView<Proxied = Self> + Sized {
type View<'msg>: ViewProxy<'msg, Proxied = Self>
where
Self: 'msg;
}
pub trait MutProxied: SealedInternal + Proxied + AsMut<MutProxied = Self> {
type Mut<'msg>: MutProxy<'msg, MutProxied = Self>
where
Self: 'msg;
}
#[allow(dead_code)]
pub type View<'msg, T> = <T as Proxied>::View<'msg>;
#[allow(dead_code)]
pub type Mut<'msg, T> = <T as MutProxied>::Mut<'msg>;
pub trait AsView: SealedInternal {
type Proxied: Proxied;
fn as_view(&self) -> View<'_, Self::Proxied>;
}
pub trait IntoView<'msg>: SealedInternal + AsView {
fn into_view<'shorter>(self) -> View<'shorter, Self::Proxied>
where
'msg: 'shorter;
}
pub trait AsMut: SealedInternal + AsView<Proxied = Self::MutProxied> {
type MutProxied: MutProxied;
fn as_mut(&mut self) -> Mut<'_, Self::MutProxied>;
}
pub trait IntoMut<'msg>: SealedInternal + AsMut {
fn into_mut<'shorter>(self) -> Mut<'shorter, Self::MutProxied>
where
'msg: 'shorter;
}
pub trait Proxy<'msg>:
SealedInternal + 'msg + IntoView<'msg> + Sync + Unpin + Sized + Debug
{
}
pub trait ViewProxy<'msg>: SealedInternal + Proxy<'msg> + Send {}
pub trait MutProxy<'msg>: SealedInternal + Proxy<'msg> + AsMut + IntoMut<'msg> {
fn get(&self) -> View<'_, Self::Proxied> {
self.as_view()
}
}
pub trait IntoProxied<T: Proxied> {
#[doc(hidden)]
fn into_proxied(self, _private: Private) -> T;
}
impl<T: Proxied> IntoProxied<T> for T {
fn into_proxied(self, _private: Private) -> T {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use googletest::prelude::*;
#[derive(Debug, Default, PartialEq)]
struct MyProxied {
val: String,
}
impl MyProxied {
fn as_view(&self) -> View<'_, Self> {
MyProxiedView { my_proxied_ref: self }
}
fn as_mut(&mut self) -> Mut<'_, Self> {
MyProxiedMut { my_proxied_ref: self }
}
}
impl SealedInternal for MyProxied {}
impl Proxied for MyProxied {
type View<'msg> = MyProxiedView<'msg>;
}
impl AsView for MyProxied {
type Proxied = Self;
fn as_view(&self) -> MyProxiedView<'_> {
self.as_view()
}
}
impl MutProxied for MyProxied {
type Mut<'msg> = MyProxiedMut<'msg>;
}
impl AsMut for MyProxied {
type MutProxied = Self;
fn as_mut(&mut self) -> MyProxiedMut<'_> {
self.as_mut()
}
}
#[derive(Debug, Clone, Copy)]
struct MyProxiedView<'msg> {
my_proxied_ref: &'msg MyProxied,
}
impl<'msg> SealedInternal for MyProxiedView<'msg> {}
impl MyProxiedView<'_> {
fn val(&self) -> &str {
&self.my_proxied_ref.val
}
}
impl<'msg> Proxy<'msg> for MyProxiedView<'msg> {}
impl<'msg> ViewProxy<'msg> for MyProxiedView<'msg> {}
impl<'msg> AsView for MyProxiedView<'msg> {
type Proxied = MyProxied;
fn as_view(&self) -> MyProxiedView<'msg> {
*self
}
}
impl<'msg> IntoView<'msg> for MyProxiedView<'msg> {
fn into_view<'shorter>(self) -> MyProxiedView<'shorter>
where
'msg: 'shorter,
{
self
}
}
#[derive(Debug)]
struct MyProxiedMut<'msg> {
my_proxied_ref: &'msg mut MyProxied,
}
impl<'msg> SealedInternal for MyProxiedMut<'msg> {}
impl<'msg> Proxy<'msg> for MyProxiedMut<'msg> {}
impl<'msg> AsView for MyProxiedMut<'msg> {
type Proxied = MyProxied;
fn as_view(&self) -> MyProxiedView<'_> {
MyProxiedView { my_proxied_ref: self.my_proxied_ref }
}
}
impl<'msg> IntoView<'msg> for MyProxiedMut<'msg> {
fn into_view<'shorter>(self) -> View<'shorter, MyProxied>
where
'msg: 'shorter,
{
MyProxiedView { my_proxied_ref: self.my_proxied_ref }
}
}
impl<'msg> AsMut for MyProxiedMut<'msg> {
type MutProxied = MyProxied;
fn as_mut(&mut self) -> MyProxiedMut<'_> {
MyProxiedMut { my_proxied_ref: self.my_proxied_ref }
}
}
impl<'msg> IntoMut<'msg> for MyProxiedMut<'msg> {
fn into_mut<'shorter>(self) -> MyProxiedMut<'shorter>
where
'msg: 'shorter,
{
self
}
}
impl<'msg> MutProxy<'msg> for MyProxiedMut<'msg> {}
#[gtest]
fn test_as_view() {
let my_proxied = MyProxied { val: "Hello World".to_string() };
let my_view = my_proxied.as_view();
assert_that!(my_view.val(), eq(&my_proxied.val));
}
fn reborrow_mut_into_view<'msg>(x: Mut<'msg, MyProxied>) -> View<'msg, MyProxied> {
x.into_view() }
#[gtest]
fn test_mut_into_view() {
let mut my_proxied = MyProxied { val: "Hello World".to_string() };
reborrow_mut_into_view(my_proxied.as_mut());
}
fn require_unified_lifetimes<'msg>(_x: Mut<'msg, MyProxied>, _y: View<'msg, MyProxied>) {}
#[gtest]
fn test_require_unified_lifetimes() {
let mut my_proxied = MyProxied { val: "Hello1".to_string() };
let my_mut = my_proxied.as_mut();
{
let other_proxied = MyProxied { val: "Hello2".to_string() };
let other_view = other_proxied.as_view();
require_unified_lifetimes(my_mut, other_view);
}
}
fn reborrow_generic_as_view<'a, 'b, T>(
x: &'b mut Mut<'a, T>,
y: &'b View<'a, T>,
) -> [View<'b, T>; 2]
where
T: MutProxied,
'a: 'b,
{
[x.as_view(), y.as_view()]
}
#[gtest]
fn test_reborrow_generic_as_view() {
let mut my_proxied = MyProxied { val: "Hello1".to_string() };
let mut my_mut = my_proxied.as_mut();
let my_ref = &mut my_mut;
{
let other_proxied = MyProxied { val: "Hello2".to_string() };
let other_view = other_proxied.as_view();
reborrow_generic_as_view::<MyProxied>(my_ref, &other_view);
}
}
fn reborrow_generic_view_into_view<'a, 'b, T>(
x: View<'a, T>,
y: View<'b, T>,
) -> [View<'b, T>; 2]
where
T: Proxied,
'a: 'b,
{
[x.into_view(), y]
}
#[gtest]
fn test_reborrow_generic_into_view() {
let my_proxied = MyProxied { val: "Hello1".to_string() };
let my_view = my_proxied.as_view();
{
let other_proxied = MyProxied { val: "Hello2".to_string() };
let other_view = other_proxied.as_view();
reborrow_generic_view_into_view::<MyProxied>(my_view, other_view);
}
}
fn reborrow_generic_mut_into_view<'a, 'b, T>(x: Mut<'a, T>, y: View<'b, T>) -> [View<'b, T>; 2]
where
T: MutProxied,
'a: 'b,
{
[x.into_view(), y]
}
#[gtest]
fn test_reborrow_generic_mut_into_view() {
let mut my_proxied = MyProxied { val: "Hello1".to_string() };
let my_mut = my_proxied.as_mut();
{
let other_proxied = MyProxied { val: "Hello2".to_string() };
let other_view = other_proxied.as_view();
reborrow_generic_mut_into_view::<MyProxied>(my_mut, other_view);
}
}
fn reborrow_generic_mut_into_mut<'a, 'b, T>(x: Mut<'a, T>, y: Mut<'b, T>) -> [Mut<'b, T>; 2]
where
T: MutProxied,
'a: 'b,
{
let tmp: Mut<'b, T> = x.into_mut();
[tmp, y]
}
#[gtest]
fn test_reborrow_generic_mut_into_mut() {
let mut my_proxied = MyProxied { val: "Hello1".to_string() };
let my_mut = my_proxied.as_mut();
{
let mut other_proxied = MyProxied { val: "Hello2".to_string() };
let other_mut = other_proxied.as_mut();
reborrow_generic_mut_into_mut::<MyProxied>(my_mut, other_mut);
}
}
}