Package List inheritance by abusing deref

Signed-off-by: Luca Fulchir <luca.fulchir@runesauth.com>
This commit is contained in:
Luca Fulchir 2024-02-16 19:34:33 +01:00
parent 690ba52c67
commit 6f8fc593d7
Signed by: luca.fulchir
GPG Key ID: 8F6440603D13A78E
4 changed files with 59 additions and 37 deletions

View File

@ -31,7 +31,14 @@ macro_rules! moduse {
}
pub use moduse;
pub trait PkgList {}
pub trait PkgsList {}
///
/// This is an empty Package List. Will be available in the main library
///
#[derive(::std::default::Default)]
pub struct PkgsEmpty {}
impl PkgsList for PkgsEmpty {}
pub trait Pkg: Any {
fn as_any(&self) -> &dyn Any

View File

@ -20,17 +20,12 @@ mod libt;
mod pkgs;
fn main() {
use pkgs::Pkgs1NewPkgs;
use pkgs::Pkgs1Pkgs;
let pkgs1 = pkgs::Pkgs1 {};
use pkgs::Pkgs2NewPkgs;
use pkgs::Pkgs2Pkgs;
let pkgs2 = pkgs::Pkgs2 {};
use pkgs::*;
let pkgs1 = pkgs::Pkgs1::default();
let pkgs2 = pkgs::Pkgs2::default();
println!("{}", Pkgs1::one().my_attr);
println!("{}", Pkgs1::two().my_attr);
println!("{}", <Pkgs2 as Pkgs1NewPkgs>::one().my_attr);
println!("{}", <Pkgs2 as Pkgs2NewPkgs>::two().my_attr);
println!("{}", Pkgs2::three().my_attr);
println!("pkgs1 - 1:{}", pkgs1.one().my_attr);
println!("pkgs1 - 2:{}", pkgs1.two().my_attr);
println!("pkgs2 - 1:{}", pkgs2.one().my_attr);
println!("pkgs2 - 2:{}", pkgs2.two().my_attr);
println!("pkgs2 - 3:{}", pkgs2.three().my_attr);
}

View File

@ -15,53 +15,73 @@
* limitations under the License.
*/
//!
//! Example of two package repositories, where one
//! extends ancd changes another
//!
use crate::libt;
//use ::std::{boxed::Box, vec::Vec};
crate::libt::moduse! {
one
two
three
two
three
}
///
/// This is a Package List
/// This is a base Package List
///
/// eventually all this will be replaced by macros
pub struct Pkgs1 {}
#[derive(::std::default::Default)]
pub struct Pkgs1 {
base: libt::PkgsEmpty,
}
/// eventually PkgsList and deref will be replaced by macros
impl libt::PkgsList for Pkgs1 {}
impl ::std::ops::Deref for Pkgs1 {
type Target = libt::PkgsEmpty;
fn deref(&self) -> &libt::PkgsEmpty {
&self.base
}
}
pub trait Pkgs1NewPkgs {
fn one() -> One {
impl Pkgs1 {
/// Packages like this can become a macro
pub fn one(&self) -> One {
One::new()
}
fn two() -> Two {
/// Packages like this can become a macro
pub fn two(&self) -> Two {
Two::new()
}
}
pub trait Pkgs1Pkgs: Pkgs1NewPkgs + libt::PkgList {}
impl Pkgs1NewPkgs for Pkgs1 {}
//impl<Pkgs1: Pkgs1NewPkgs + libt::PkgList> Pkgs1Pkgs for Pkgs1 {}
impl<Pkgs1: Pkgs1NewPkgs + libt::PkgList> Pkgs1Pkgs for Pkgs1 {}
///
/// This is a Package List that extends and changes Pkgs1
///
/// eventually all this will be replaced by macros
pub struct Pkgs2 {}
#[derive(::std::default::Default)]
pub struct Pkgs2 {
base: Pkgs1,
}
/// eventually PkgsList and deref will be replaced by macros
impl libt::PkgsList for Pkgs2 {}
pub trait Pkgs2NewPkgs {
fn two() -> Two {
impl ::std::ops::Deref for Pkgs2 {
type Target = Pkgs1;
fn deref(&self) -> &Pkgs1 {
&self.base
}
}
impl Pkgs2 {
/// example of option override in a package
pub fn two(&self) -> Two {
let mut t = Two::new();
t.my_attr = 42;
t
}
fn three() -> Three {
/// Packages like this can become a macro
pub fn three(&self) -> Three {
Three::new()
}
}
pub trait Pkgs2Pkgs: Pkgs2NewPkgs + Pkgs1Pkgs {}
impl<Pkgs2: Pkgs2NewPkgs + Pkgs1Pkgs> Pkgs2Pkgs for Pkgs2 {}
impl Pkgs2NewPkgs for Pkgs2 {}
impl Pkgs1NewPkgs for Pkgs2 {}

View File

@ -25,6 +25,6 @@ impl libt::Pkg for Three {}
impl Three {
pub fn new() -> Self {
Three { my_attr: 42 }
Three { my_attr: 3 }
}
}