///all structs
#[allow(warnings)]
pub mod structs {
    /// ## CopyString
    ///```ignore
    /// use doe::CopyString;
    /// let mut s = CopyString::default();
    /// s.push_str("11");
    /// s.push_str("22");
    /// s.push_str("33");
    /// s.push_str("44");
    /// dbg!(s);
    /// s.println();
    /// let a = s;
    /// let b = a;
    /// b.println();
    /// ```
    #[derive(Debug, Clone, Copy)]
    pub struct CopyString {
        pub val: std::ptr::NonNull<String>,
    }

    impl From<&str> for CopyString {
        fn from(s: &str) -> Self {
            CopyString::new(s)
        }
    }

    impl From<String> for CopyString {
        fn from(s: String) -> Self {
            CopyString::new(s)
        }
    }

    impl std::ops::Deref for CopyString {
        type Target = String;
        fn deref(&self) -> &Self::Target {
            unsafe { self.val.as_ref() }
        }
    }
    impl std::ops::DerefMut for CopyString {
        fn deref_mut(&mut self) -> &mut Self::Target {
            unsafe { self.val.as_mut() }
        }
    }
    impl Default for CopyString {
        fn default() -> Self {
            Self::new(String::default())
        }
    }
    impl CopyString {
        pub fn from_str(s: &str) -> Self {
            let ptr = std::ptr::NonNull::from(Box::leak(Box::new(s.to_string())));
            Self { val: ptr }
        }
        pub fn new<T>(s: T) -> Self
        where
            T: AsRef<str>,
        {
            let ptr = std::ptr::NonNull::from(Box::leak(Box::new(s.as_ref().to_string())));
            Self { val: ptr }
        }
        pub fn to_string(&self) -> String {
            unsafe {
                let res = &*self.val.as_ptr();
                res.to_string()
            }
        }
    }
    use std::default::Default;
    use std::fmt::{self, Debug, Display};
    use std::ops::{Deref, RangeBounds};
    ///## implments Bfn struct and bfn! macro for Box<dyn Fn()> trait object
    ///```rust
    ///fn main() {
    ///    use doe::*;
    ///
    ///    #[derive(Debug)]
    ///    struct Demo<'a>{
    ///        name:&'a str
    ///    }
    ///    fn func()->Demo<'static>{
    ///        let d = Demo{name: "andrew"};
    ///        d
    ///    }
    ///    let f1 = bfn!(func);
    ///    f1.call().dprintln();
    ///
    ///    fn sum()->usize{
    ///        9+89
    ///    }
    ///    let f2 = Bfn::new(Box::new(sum));//or bfn!(sum);
    ///    f2.call().println();
    ///}
    ///```
    pub struct Bfn<T: Unpin>(Box<dyn Fn() -> T>);
    impl<T: Unpin> Bfn<T> {
        pub fn new(v: Box<dyn Fn() -> T>) -> Self {
            Self(v)
        }
        pub fn new_fn(v: &'static dyn Fn() -> T) -> Self {
            Self::new(Box::new(v))
        }
        pub fn call(&self) -> T {
            self.0.deref()()
        }
    }
    ///## implments Bts struct and bts! macro for Box<\dyn ToString> trait object
    /// ```rust
    ///fn main() {
    ///    use doe::*;
    ///    let mut s:Bts =  bts!("Trait Object, it's ");
    ///    s.push(bts!(100));
    ///    s.push_str("% safe");
    ///    s.dprintln();//"Trait Object, it's 100% safe"
    ///    s.as_bytes().dprintln();//[84, 114, 97, 105, 116, 32, 79, 98, 106, 101, 99, 116, 44, 32, 105, 116, 39, 115, 32, 49, 48, 48, 37, 32, 115, 97, 102, 101]
    ///    s.chars().dprintln();//['T', 'r', 'a', 'i', 't', ' ', 'O', 'b', 'j', 'e', 'c', 't', ',', ' ', 'i', 't', '\'', 's', ' ', '1', '0', '0', '%', ' ', 's', 'a', 'f', 'e']
    ///    let b = Into::<Bts>::into("b".to_string());
    ///    let b = Bts::from("demo");
    ///}
    ///```
    pub struct Bts(Box<dyn ToString>);

    impl Bts {
        ///
        /// ```rust
        ///fn main() {
        ///    use doe::*;
        ///    let mut s:Bts =  bts!("Trait Object, it's ");
        ///    s.push(bts!(100));
        ///    s.push_str("% safe");
        ///    s.dprintln();//"Trait Object, it's 100% safe"
        ///    s.as_bytes().dprintln();//[84, 114, 97, 105, 116, 32, 79, 98, 106, 101, 99, 116, 44, 32, 105, 116, 39, 115, 32, 49, 48, 48, 37, 32, 115, 97, 102, 101]
        ///    s.chars().dprintln();//['T', 'r', 'a', 'i', 't', ' ', 'O', 'b', 'j', 'e', 'c', 't', ',', ' ', 'i', 't', '\'', 's', ' ', '1', '0', '0', '%', ' ', 's', 'a', 'f', 'e']
        ///    let b = Into::<Bts>::into("b".to_string());
        ///    let b = Bts::from("demo");
        ///}
        ///```
        pub fn new(v: Box<dyn ToString>) -> Bts {
            Self(v)
        }
        pub fn push_str(&mut self, string: &str) {
            let mut self_string = self.0.to_string();
            self_string.push_str(string);
            self.0 = Box::new(self_string);
        }
        ///
        /// ```rust
        ///    use doe::*;
        ///    let mut s:Bts =  bts!("Trait Object, it's ");
        ///    s.push(bts!(100));
        ///    s.push_str("% safe");
        ///    s.println();//"Trait Object, it's 100% safe"
        ///    s.as_bytes().dprintln();//[84, 114, 97, 105, 116, 32, 79, 98, 106, 101, 99, 116, 44, 32, 105, 116, 39, 115, 32, 49, 48, 48, 37, 32, 115, 97, 102, 101]
        ///    s.chars().dprintln();//['T', 'r', 'a', 'i', 't', ' ', 'O', 'b', 'j', 'e', 'c', 't', ',', ' ', 'i', 't', '\'', 's', ' ', '1', '0', '0', '%', ' ', 's', 'a', 'f', 'e']
        ///    let b = Into::<Bts>::into("b".to_string());
        ///    let b = Bts::from("demo");
        ///```
        pub fn push(&mut self, bts: Bts) {
            let mut self_string = self.0.to_string();
            self_string.push_str(&bts.0.as_ref().to_string());
            self.0 = Box::new(self_string);
        }
        pub fn chars(&self) -> Vec<char> {
            self.0.to_string().chars().collect()
        }
        pub fn as_bytes(&self) -> Vec<u8> {
            self.0.to_string().as_bytes().to_vec()
        }

        // pub fn to_string(&self) -> String {
        //     self.0.to_string()
        // }
    }
    impl Default for Bts {
        fn default() -> Self {
            crate::bts!("")
        }
    }

    impl Unpin for Bts {}
    unsafe impl Sync for Bts {}
    unsafe impl Send for Bts {}
    impl std::panic::RefUnwindSafe for Bts {}
    impl std::panic::UnwindSafe for Bts {}

    impl fmt::Debug for Bts {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "{:?}", self.0.to_string())
        }
    }
    impl fmt::Display for Bts {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "{}", self.0.to_string())
        }
    }
    impl Clone for Bts {
        fn clone(&self) -> Self {
            Bts::new(Box::new(self.0.to_string()))
        }
    }
    impl From<String> for Bts {
        fn from(s: String) -> Self {
            Bts(Box::new(s))
        }
    }
    impl<T: core::fmt::Debug> From<Vec<T>> for Bts {
        fn from(s: Vec<T>) -> Self {
            Bts(Box::new(format!("{:?}", s)))
        }
    }
    impl From<&str> for Bts {
        fn from(s: &str) -> Self {
            Bts(Box::new(s.to_string()))
        }
    }

    extern crate alloc;
    use alloc::sync::Arc;
    use core::mem::{self, ManuallyDrop};
    use core::task::{RawWaker, RawWakerVTable, Waker};
    /// Converts a closure into a [`Waker`].
    ///
    /// The closure gets called every time the waker is woken.
    ///
    /// # Examples
    ///
    /// ```
    /// use doe::waker_fn;
    ///
    /// let waker = waker_fn(|| println!("woken"));
    ///
    /// waker.wake_by_ref(); // Prints "woken".
    /// waker.wake();        // Prints "woken".
    /// ```
    pub fn waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> Waker {
        let raw = Arc::into_raw(Arc::new(f)) as *const ();
        let vtable = &Helper::<F>::VTABLE;
        unsafe { Waker::from_raw(RawWaker::new(raw, vtable)) }
    }

    struct Helper<F>(F);

    impl<F: Fn() + Send + Sync + 'static> Helper<F> {
        const VTABLE: RawWakerVTable = RawWakerVTable::new(
            Self::clone_waker,
            Self::wake,
            Self::wake_by_ref,
            Self::drop_waker,
        );

        unsafe fn clone_waker(ptr: *const ()) -> RawWaker {
            let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const F));
            mem::forget(arc.clone());
            RawWaker::new(ptr, &Self::VTABLE)
        }

        unsafe fn wake(ptr: *const ()) {
            let arc = Arc::from_raw(ptr as *const F);
            (arc)();
        }

        unsafe fn wake_by_ref(ptr: *const ()) {
            let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const F));
            (arc)();
        }

        unsafe fn drop_waker(ptr: *const ()) {
            drop(Arc::from_raw(ptr as *const F));
        }
    }
}
