Reputation: 439
I have function that is part of a struct (for context reasons) which does not take the self
parameter. Furthermore, the struct itself takes a generic parameter T
with some trait restrictions:
trait SomeRestriction {}
struct SomeStruct<T: SomeRestriction>(T);
impl<T: SomeRestriction> SomeStruct<T> {
fn some_function_that_does_not_take_self() -> String {
todo!()
}
}
I want to write a test and I would like to avoid giving
that function the self
parameter since mocking the object
with some generic struct parameter is a lot of effort for that small function and test.
I do it for the other tests since it is necessary there, but I would like to avoid it wherever I can.
I tried to call it like this:
let some_string = SomeStruct::some_function_that_does_not_take_self();
but it will ask me for a type annotation even though it is not needed.
Is there a way to call it without mocking the struct or removing the function from the struct implementation?
Upvotes: 2
Views: 1890
Reputation: 430290
As orlp said: no, you must provide a concrete type.
is a lot of effort for that small function and test
For your specific example, you can write the code differently so that the concrete type is easier to provide by removing the trait bounds where it isn't needed:
trait SomeRestriction {}
struct SomeStruct<T>(T);
impl<T> SomeStruct<T> {
fn some_function_that_does_not_take_self() -> String { todo!() }
}
impl<T: SomeRestriction> SomeStruct<T> {
// functions that actually use `T`
}
fn main() {
let some_string = SomeStruct::<()>::some_function_that_does_not_take_self();
}
See also:
Upvotes: 0
Reputation: 117641
Is there a way to call it without mocking the struct or removing the function from the struct implementation?
No. For all Rust knows SomeStruct<T>::some_function_that_does_not_take_self
is completely distinct for each T
. They could have different behavior, too, consider this:
use core::fmt::Debug;
#[derive(Debug, Default)] struct A;
#[derive(Debug, Default)] struct B;
struct C<T> { t: T }
impl<T: Debug + Default> C<T> {
fn foo() { println!("{:?}", T::default()) }
}
fn main() {
C::<A>::foo(); // Prints 'A'.
C::<B>::foo(); // Prints 'B'.
}
Upvotes: 7