use plusplus::{class, ClassInConstruction, Downcast, DowncastTo, InConstruction};
class!{
crate as plusplus;
#[derive(Clone)]
pub class ObjectZero {
string: String;
pub fn new() -> ObjectZero<InConstruction> {
init_class! {
string: "hello".into(),
another_field: 26,
}
}
pub(crate) another_field: i32;
pub fn set_string(&mut self, str: String) {
self.string = str;
}
}
}
mod object_one {
use plusplus::{class, InConstruction};
use reqwest::Response;
class!{
crate as plusplus;
#[derive(Clone)]
pub class ObjectOne: super::ObjectZero {
string_one: String;
reqwest_url: String;
pub fn new() -> ObjectOne<InConstruction> {
init_class! {
superclass: super::ObjectZero::new(),
string_one: String::new(),
reqwest_url: "https://crouton.net/".into(),
}
}
pub fn print_example(&self) {
println!("hi from ObjectOne");
}
pub async fn get_url(&self) -> reqwest::Result<Response> {
reqwest::get(&self.reqwest_url).await
}
override super::ObjectZero {
pub fn set_string(&mut self, str: String) {
self.super_set_string(str.clone());
self.string_one = str;
}
}
}
}
impl ObjectOne {
pub fn string_one(&self) -> &str {
&self.string_one
}
}
}
use object_one::ObjectOne;
use reqwest::Response;
class!{
crate as plusplus;
#[derive(Clone)]
pub class ObjectTwo: ObjectOne {
string_two: String;
pub fn new(two: impl Into<String>) -> ObjectTwo<InConstruction> {
init_class! {
superclass: object_one::ObjectOne::new(),
string_two: two.into(),
}
}
override ObjectOne {
pub fn print_example(&self) {
self.super_print_example();
println!("hello from ObjectTwo");
}
pub async fn get_url(&self) -> reqwest::Result<Response> {
let response = self.super_get_url().await?;
println!("url get!!!");
Ok(response)
}
}
override ObjectZero {
pub fn set_string(&mut self, str: String) {
self.super_set_string(str.clone());
self.string_two = str;
}
}
}
}
fn main() {
let object_two = ObjectTwo::new("hello!").finish();
object_two.print_example();
println!();
let object_as_one = object_two.upcast();
object_as_one.print_example();
println!();
object_as_one.my_print_example();
println!();
let mut object_as_base = object_as_one.upcast();
let new_str = "sets all strings!!";
object_as_base.set_string(new_str.to_string());
let object_as_two = object_as_base
.downcast_to::<ObjectOne>().unwrap()
.downcast_to::<ObjectTwo>().unwrap();
assert_eq!(object_as_two.string, new_str);
assert_eq!(object_as_two.string_one(), new_str);
assert_eq!(object_as_two.string_two, new_str);
let tokio_rt = tokio::runtime::Builder::new_current_thread().enable_io().build().unwrap();
tokio_rt.block_on(async {
let object_as_one = object_as_two.upcast();
let response = object_as_one.get_url().await.unwrap();
println!("{}", response.text().await.unwrap());
});
}