Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unconstrained lifetime error when implementing Index trait

Tags:

rust

I have a struct that owns a HashMap<String, String>,

struct Test {
    data: HashMap<String, String>,
}

I am trying to implement the Index trait for this type to map to the Index implementation of the hashmap (there's other logic involved so I cannot expose the hashmap).

This works if I am just getting a reference to the value in the hashmap:

impl<'b> Index<&'b str> for Test {
    type Output = String;
    fn index(&self, k: &'b str) -> &String {
        self.data.get(k).unwrap()
    }
}

However, I want to get &Option<&String> out of it, like data.get(). So I tried this:

impl<'b, 'a> Index<&'b str> for Test {
    type Output = Option<&'a String>;
    fn index(&'a self, k: &'b str) -> &Option<&'a String> {
        &self.data.get(k)
    }
}

This results in:

error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
 --> <anon>:8:10
  |
8 | impl<'b, 'a> Index<&'b str> for Test {
  |          ^^ unconstrained lifetime parameter

I understand the "unconstrained lifetime parameter in 'a". Now 'a is the lifetime of Test itself, so I want (I think) where 'Self: 'a (so self lives at least as long as 'a ) . I cannot seem to figure this out for Index impl? I tried some things with adding PhantomData to my Test. But I am not getting anywhere. Any suggestions?

like image 543
divbyzero Avatar asked Dec 23 '16 00:12

divbyzero


People also ask

What happens when ILM fails to resolve an index error?

When ILM executes a lifecycle policy, it’s possible for errors to occur while performing the necessary index operations for a step. When this happens, ILM moves the index to an ERROR step. If ILM cannot resolve the error automatically, execution is halted until you resolve the underlying issues with the policy, index, or cluster.

Why is my-index not working?

The index name must match the regex pattern ^.*-\d+ for the rollover action to work. The most common problem is that the index name does not contain trailing digits. For example, my-index does not match the pattern requirement.

Why did ILM fail to shrink my-index-000001 to 4 shards?

After five days, ILM attempts to shrink my-index-000001 from two shards to four shards. Because the shrink action cannot increase the number of shards, this operation fails and ILM moves my-index-000001 to the ERROR step. You can use the ILM Explain API to get information about what went wrong:

What are the most common problems with indexing?

The most common problem is that the index name does not contain trailing digits. For example, my-index does not match the pattern requirement. Append a numeric value to the index name, for example my-index-000001.


1 Answers

As has been pointed out in the comments, you won't be able to do exactly what you want. But, what it seems like you really want is to replicate HashMap's get method. So I would suggest either writing your own, or implmenting Deref (and not DerefMut) to give the struct's owner immutable access directly to the internal HashMap. Hopefully that means the user can't mess up your struct's internal logic. Keep in mind that if you do both then Deref will not be used to called HashMap::get because Test::get will be available.

struct FooMap {
    data: HashMap<String, String>
}

Replicating get:

impl FooMap {
    pub fn get(&self, index: &str) -> Option<&String> { self.data.get(index) }
}

Using Deref:

impl Deref for FooMap {
    type Target = HashMap<String, String>;
    fn deref(&self) -> &Self::Target { &self.data }
}

Example code on Rust Playground

like image 78
ampron Avatar answered Oct 16 '22 01:10

ampron