use super::*;
use crate::*;
#[derive(Debug,PartialBorrow)]
#[partial_borrow(Debug)]
struct AB {
a: usize,
b: String,
}
impl Default for AB {
fn default() -> Self { Self { a: 42, b: "hello".into() } }
}
impl AB {
fn bump(&mut self) {
self.a += 1;
self.b.push('|');
println!("-----\n{:?}", self);
}
fn use_const(&self) {
println!("{:?}", self);
}
}
#[ext]
impl partial!(AB mut a, !*) {
fn use_mut_a(&mut self) { *self.a += 10; }
}
#[ext]
impl partial!(AB const a, !*) {
fn use_const_a(&self) { println!("{}", &*self.a); }
}
#[ext]
impl partial!(AB mut b, !*) {
fn use_mut_b(&mut self) { self.b.push('U'); }
}
#[ext]
impl partial!(AB const b, !*) {
fn use_const_b(&self) { println!("{}", &*self.b); }
}
macro_rules! test_downgrade { {
$tfn:ident, $downgrade:path, $downgrade_mut:path
} => {
#[test]
fn $tfn() {
println!("downgrade {}", stringify!($tfn));
let mut ab = AB::default();
let a: &mut partial!(AB mut a) = $downgrade_mut(&mut ab);
*a.a += 1;
a.as_mut().use_mut_a();
println!("{:?}", a);
let a: &partial!(AB) = $downgrade(&ab);
let a_ab = &**a;
println!("{:?}", a_ab);
a.use_const();
a_ab.use_const();
ab.bump();
let a: &mut partial!(AB const a, !*) = $downgrade_mut(&mut ab);
println!("{}", &*a.a);
a.use_const_a();
println!("{:?}", a);
let a0: &partial!(AB mut a, !*) = $downgrade(&ab);
let a1: &partial!(AB const a, !*) = $downgrade(&ab);
println!("{} {}", &*a0.a, &*a1.a);
a0.as_ref().use_const_a();
a1.use_const_a();
println!("{:?} {:?}", a0, a1);
ab.bump();
}
}}
test_downgrade!{ downgrade, Downgrade::downgrade, Downgrade::downgrade_mut }
test_downgrade!{ asref, AsRef::as_ref, AsMut::as_mut }
macro_rules! test_split { {
$tfn:ident, $split:path, $split_mut:path
} => {
#[test]
fn $tfn() {
println!("split {}", stringify!($tfn));
let mut ab = AB::default();
let (a,b): (&mut partial!(AB mut a, !*),
&mut partial!(AB mut b, !*)) = $split_mut(&mut ab);
*a.a += 1;
*b.b += "+";
a.use_mut_a();
b.use_mut_b();
println!("{:?} {:?}", a, b);
ab.bump();
let (a,b): (&mut partial!(AB const a, !*),
&mut partial!(AB const a, mut *)) = $split_mut(&mut ab);
println!("{}", &*a.a);
*b.b += "#";
a.use_const_a();
b.as_mut().use_mut_b();
println!("{:?} {:?}", a, b);
let (a,b): (&mut partial!(AB),
&mut partial!(AB)) = $split_mut(&mut ab);
println!("{} {}", &*a.a, &*b.b);
a.as_ref().use_const_a();
b.as_ref().use_const_b();
let a_ab = &**a;
let b_ab = &**b;
println!("{:?} {:?} {:?} {:?}", a, b, a_ab, b_ab);
a.use_const();
b.use_const();
a_ab.use_const();
b_ab.use_const();
ab.bump();
let (a,b): (&partial!(AB mut a, !*),
&partial!(AB mut b, !*)) = $split(&ab);
println!("{} {}", &*a.a, &*b.b);
a.as_ref().use_const_a();
b.as_ref().use_const_b();
println!("{:?} {:?}", a, b);
ab.bump();
let (a,b): (&partial!(AB const a, !*),
&partial!(AB const a, mut *)) = $split(&ab);
println!("{} {}", &*a.a, &*b.b);
a.use_const_a();
b.as_ref().use_const_b();
println!("{:?} {:?}", a, b);
ab.bump();
}
}}
test_split!{ split_off, SplitOff::split_off, SplitOff::split_off_mut }
test_split!{ split_into, SplitInto::split_into, SplitInto::split_into_mut }
test_split!{ split_into_into, Into::into, Into::into }
test_split!{ split_from_from, From::from, From::from }