I'm playing with Rust and here is the code:
pub trait TFilter {
fn get_text(&self) -> &String;
}
...
pub struct ContentFilter {
text: String,
domains: String,
body: String,
}
impl TFilter for ContentFilter {
fn get_text(&self) -> &String {
return &self.text
}
}
impl ContentFilter {
pub fn from_text(text: String, domains: String, body: String) -> Self {
return ContentFilter {
text,
domains,
body
}
}
}
...
fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter> {
...
&Box::new(ContentFilter::from_text(text, domains, body)) // is returned
...
}
I'm getting the error message:
expected trait object
dyn filter::TFilter, found structfilter::ContentFilter
= note: expected reference
&std::boxed::Box<(dyn filter::TFilter + 'static)>found reference&std::boxed::Box<filter::ContentFilter>
This is misleading as:
- it does implements the trait
- the compiler does know the size of
ContentFilterstruct
Any clue?
PS. The code is not good anyway (as it's unclear who owns the Box that is returned), but the message is misleading.
PPS. How a caching proxy can be implemented then:
pub trait TFilterBuilder {
fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter>;
}
...
struct FilterCachingProxy {
filter_builder: Box<dyn TFilterBuilder>,
cache: Box<dyn TFilterCache>
}
impl FilterCachingProxy {
fn new_for_builder(filter_builder: Box<dyn TFilterBuilder>, cache: Box<dyn TFilterCache>) -> Self {
return FilterCachingProxy {
filter_builder,
cache
}
}
}
impl TFilterBuilder for FilterCachingProxy {
fn filter_from_text(&mut self, text: String) -> &Box<dyn TFilter> {
let boxed_filter = match self.cache.get(&text) {
Some(found_boxed_filter) => found_boxed_filter,
_ => {
// delegate creation to wrapped TFilterBuilder impl (`filter_builder`)
let boxed_filter = self.filter_builder.filter_from_text(text.clone());
// ... and put to the cache
self.cache.put(&text, &boxed_filter); // boxed_filter should be moved to make cache own it?
&boxed_filter // looks strange: who owns it then?
}
};
return boxed_filter;
}
}