Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Vec<u8> is recognised as Array rather than Bytes #296

Closed
dracarys18 opened this issue Sep 24, 2024 · 6 comments
Closed

[Bug] Vec<u8> is recognised as Array rather than Bytes #296

dracarys18 opened this issue Sep 24, 2024 · 6 comments
Assignees
Labels
bug Something isn't working

Comments

@dracarys18
Copy link
Contributor

Fred version - 9.2.1
Redis version - 7.0.1
Platform - mac
Deployment type - cluster|sentinel|centralized

Describe the bug
For the following example below, Fred throws and error value: Redis Error - kind: InvalidArgument, details: Invalid argument type: Array while it's a valid type.

    let v = client.hsetnx::<E, &str, &str, V>("bruh1", "what1", serde_json::to_vec(&data).unwrap()).await;

To Reproduce
Steps to reproduce the behavior:

  1. Call hsetnx function with Vec<u8> as value type.

Logs
(If possible set RUST_LOG=fred=trace and run with --features debug-ids)

Redis Error - kind: InvalidArgument, details: Invalid argument type: Array

@dracarys18 dracarys18 added the bug Something isn't working label Sep 24, 2024
@dracarys18
Copy link
Contributor Author

I can take this up we need a different TryInto implementation for Vec<u8> and Vec<T> where T is not u8

@aembke
Copy link
Owner

aembke commented Oct 17, 2024

Hi @dracarys18,

Unfortunately I'm not sure how to do this on stable rust at the moment without specialization, but feel free to submit a PR if you can make it work.

After looking at this a bit more - If I'm reading this correctly it looks like TryFrom<T> creates a From<T> fallback automatically, and since From<u8> already exists we can't implement both TryFrom<Vec<u8>> for RedisValue and TryFrom<Vec<T>> for RedisValue.

I think there's a few ways to work around this, but they have some downsides:

  • Convert to Vec<RedisValue::Integer> and back to bytes (safe but expensive)
  • Wait for specialization (unstable at the moment)
  • Remove the From<u8> for RedisValue impl (breaking)
  • Use mem::transmute (unsafe, and probably not useful since it would have to be used with TypeId::of(), which requires T: 'static, which is breaking)
  • Use a different trait other than TryFrom to do these type conversions so we can detect Vec<u8> in the same manner that FromRedis uses (breaking)

For the next major version I'll probably remove the From<u8> for RedisValue since Vec<u8> is likely much more common, but for now I want to avoid any breaking changes.

@dracarys18
Copy link
Contributor Author

@aembke I like the idea of last point can we make a feature flag for this so it wont break for others and slowly release it in the next release

@aembke
Copy link
Owner

aembke commented Oct 31, 2024

Sounds good. In 9.4.0 there a new FF specialize-into-bytes that will disable From<u8> for RedisValue and enable TryFrom<Vec<u8>> for RedisValue such that it uses RedisValue::Bytes.

@dracarys18
Copy link
Contributor Author

Oh that's awesome! Thanks @aembke

@aembke
Copy link
Owner

aembke commented Nov 7, 2024

Added in 9.4.0

@aembke aembke closed this as completed Nov 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants