Returning a trait reference as a singleton

Hi,

I am new to rust and am trying to implement a singleton as a static method which returns a reference to a trait.

pub mod Auth {

    use chrono::{DateTime, Utc};
    use md5;
    use std::collections::HashMap;
    use std::sync::Arc;
    use std::sync::RwLock;

    lazy_static! {
        static ref ai: Arc<dyn AuthInterface> = Arc::new(AuthImpl::new());
    }

    pub trait AuthInterface {
        fn register_user(&self, email: &str, pwd: &str) -> String;
    }

    pub fn getAuthInterface() -> Arc<dyn AuthInterface> {
/ getting an error here - 
// mismatched types - expected struct `std::sync::Arc`, found struct `ims::Auth::ai`

        return ai;
    }

    struct AuthImpl {
        usr_record_store: RwLock<HashMap<String, String>>,
    }

    impl AuthInterface for AuthImpl {
        fn register_user(&self, email: &str, pwd: &str) -> String {
            return String::from("");
        }
    }

    impl AuthImpl {
        pub fn new() -> AuthImpl {
            AuthImpl {
                usr_record_store: RwLock::new(HashMap::new()),
            }
        }
    }

How can i have a singleton static method that returns a trait

1 Like

Try with return ai.clone(); (btw, the return part is not needed).

why

Basically, you've been bitten by the macro sugar:

lazy_static! {
    static ref ai: Arc<dyn AuthInterface> …
}

is actually defining something like:

    struct ai; /* i.e.
    struct ai {} // dummy type
    const ai: ai = ai {}; // dummy constant */

    /// `*ai : Arc<dyn …>`
    impl Deref for ai {
        type Target = Arc<dyn AuthInterface>;
        …
    }

(That Deref is what allows .methods() to work as if they were applied on the Target type)

1 Like

You'll need to clone the Arc in order to return it:

    pub fn getAuthInterface() -> Arc<dyn AuthInterface> {
        ai.clone();
    }

(Note, cloning the Arc will create a new pointer to the same singleton. It won't clone the underlying value.)

You will probably also need to use dyn AuthInterface + Sync + Send, or add those as bounds to the AuthInterface trait itself.

1 Like

Thanks Everyone. I used Arc clone with Sync + Send as bounds aded to the AuthInterface trait and removed the return also.