partial-borrow 1.0.1

Partially borrow a struct
Documentation
// Copyright 2021 Ian Jackson and contributors
// SPDX-License-Identifier: GPL-3.0-or-later
// There is NO WARRANTY.

use std::fmt::Debug;

use crate::prelude::*;
use crate::perms::{No,Mut};

//#[derive(Debug)]
#[derive(Debug,PartialBorrow)]
#[partial_borrow(Debug)]
struct ABC<'d, C, const E: u8>
  where C: Clone, C: CX<X>
{
  a: usize,
  a0: X,
  pub b: String,
  pub c: C,
  pub d: &'d str,
  x: X,
}

#[derive(Debug)]
struct X;
impl X { fn use_mut(&mut self) -> &'static str { "X" } }

trait CX<XT> { }
impl CX<X> for char { }

type OnlyA = partial!(ABC<'static,char,1> mut a a0, ! *, const c);
//type OnlyA = ABC__Partial<'static, Mut,No,No,No,No char,1>;
type OnlyB = ABC__Partial<'static, No,No,Mut,No,No,No, char,1>;

//type OnlyNone = partial!(ABC<'static,char,1>);

fn use_a(a: &mut OnlyA) {
  *a.a += 1;
  eprintln!("use_a: {:?} {:?}", &*a.a, a.a0.use_mut());
}
fn use_b(b: &mut OnlyB) {
  *b.b += "+";
  eprintln!("use_b: {:?}", &*b.b);
}

#[test]
pub fn test() {
  let mut whole = ABC {
    a: 42,
    a0: X,
    b: format!("hi"),
    c: 'c',
    d: "d",
    x: X,
  };
  let whole = &mut whole;
  eprintln!("real {:?}", whole);
  let (a,b): (&mut OnlyA, &mut OnlyB) = whole.into();
  use_a(a); use_b(b);
  use_a(a); use_b(b);
  use_a(a); use_b(b);
  fn expect_debug(v: &str, s: &dyn Debug, exp: &str) {
    let got = format!("{:?}", s);
    eprintln!("{}={}", v, got);
    assert_eq!(got, format!("ABC__Partial {{ {} }}", exp));
  }
  eprintln!("b={:?}", &b);
  expect_debug("a", &a, r#"a: 45, a0: X, b: _, c: 'c', d: _, x: _"#);
  expect_debug("b", &b, r#"a: _, a0: _, b: "hi+++", c: _, d: _, x: _"#);
}