Использование объектов-черт в структурах без использования параметра типа - PullRequest
1 голос
/ 18 февраля 2020

Можно ли инкапсулировать объект признака в структуру?

Насколько я могу судить, требуется main, чтобы знать о типе A, независимо от того, сколько уровней модулей между. Я пытаюсь сделать реализацию по умолчанию, чтобы внутренняя часть могла оставаться такой. Мой текущий пример использования с чертой yup_oauth2::GetToken.

Мой текущий интерфейс:

// root_project/main.rs
let auth_obj = build_auth_obj("user", "pass");
let root_caller: ApiUser<_> = ApiUser::new(auth_obj);

// api_user/lib.rs
pub struct ApiUser<A> {
    stored_api: API<A>,
}

impl ApiUser<A>
where
    A: yup_oauth2::GetToken,
{
    fn new(auth_obj: A) -> API<A> {
        stored_api: API::new(auth_obj)
    }
}

// api_def/lib.rs
struct Api<A> {
    auth: Refcell<A>,
}

impl<A> Api<A>
where
    A: yup_oauth2::GetToken,
{
    fn new(auth: A) -> Api<A> {
        API {
            auth: RefCell::new(auth),
        }
    }
}

Мой желаемый интерфейс:

// root_project/main.rs
let root_caller: ApiUser = ApiUser::new("user", "pass");

// api_user/lib.rs
pub struct ApiUser {
    stored_api: API,
}

impl ApiUser {
    fn new(username: String, password: String) -> API {
        stored_api: API::new(username, password)
    }
}

// api_def/lib.rs
pub struct API(ApiImpl<dyn yup_oauth2::GetToken>);

struct ApiImpl<A> {
    auth: Refcell<A>,
}

impl<A> ApiImpl<A>
where
    A: yup_oauth2::GetToken,
{
    fn new(username: String, password: String) -> ApiImpl<A> {
        ApiImpl {
            auth: RefCell::new(build_auth_obj(username, password)),
        }
    }
}
...