RangeBound Not Working

I have a Map and I want to get all keys and values for a given ID, I created a RangeBound filter function, but the problem is filter is not working well and returns the whole map. Anyone guide me. Thanks!


    pub fn get_seller_insurance_contract_by_princicpal() -> Vec<InsuranceSellersKey> {
        read_state(|s| {
            s.stable_state
                .insurance_sellers
                .range(filter_seller_insurance_contract_by_principal(ic_cdk::caller()))
                .map(|(k, _)| k)
                .collect()
        })
    }


pub fn filter_seller_insurance_contract_by_principal(principal: Principal) -> impl RangeBounds<InsuranceSellersKey> {
    let start: InsuranceSellersKey = InsuranceSellersKey {
        principal,
        insurance_id: u32::MIN,
    };
    let end: InsuranceSellersKey = InsuranceSellersKey {
        principal,
        insurance_id: u32::MAX,
    };

    start..end
}

It's impossible to tell what the problem is because the code you posted is missing a ton of context.

Please post a complete example in the Playground that reproduces the issue (for example, an assertion that should pass but fails).

I want to return the list of keys to the principal who participated in insurance that is why I passed ic_cdk::caller() which takes the function calling user-principal. If the user participates it will return the list of insurance.
I participated from another principal, but when calling the function from another principal the expected result should be Vec<> but I got all entries of the map

From your code, it seems you are calling range on a BTreeMap using a custom key type containing a custom Principal field and a u32 field. A minimal playground example shows this works as expected. Could you augment the example to reproduce the problem? Possible culprits might be the Ord impl on the Key or Principal types or the Principal argument passed to your filter_seller_insurance_contract_by_principal.

As a side note, you probably meant to use an inclusive range (start..=end instead of start..end).

Again, that's a high-level description which is still somewhat hard to understand. Please post executable code that demonstrates the problem.

There is an Ord on the Principal

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Principal {
    /// Length.
    len: u8,

    /// The content buffer. When returning slices they should always be sized according to
    /// `len`.
    bytes: [u8; Self::MAX_LENGTH_IN_BYTES],
}

This code runs inside the wasm module, I don't know how to use Playground for that.

You could, for example, copy your principal type to the playground example and modify the key type to use it instead of the current &'static str. Then check if the output is still correct. The goal is to find a minimal example that exhibits the problem you are experiencing. If you are able to find that, click "share" to generate a new link, and post it here.

Most rust code, apart from I/O functions, should not care if it's run on wasm or on the playground or anywhere else.

1 Like

The generated Eq/PartialEq/Ord/PartialOrd for this will compare the entire bytes fields when the len fields are equal. That's probably not what you want, unless you can guarantee that the unused bytes (past len) are initialized to something that makes the comparison work. It may be a different problem and not what is causing your reported problem, but worth fixing anyway (if in fact it is incorrect).

1 Like