cdrs
cdrs copied to clipboard
How to use cdrs blob type for serde?
Hi I am novice in Rust, and tried something like this:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize, Debug, TryFromRow)]
pub struct Data {
#[serde(with = "my_blob")]
pub hash: Blob
}
pub mod my_blob {
use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
use std::str::FromStr;
use cdrs::types::{blob::*, value::*};
use cdrs::types::data_serialization_types::decode_blob;
pub fn serialize<S>(val: &Blob, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
val.into_vec().serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Blob, D::Error>
where
D: Deserializer<'de>,
{
let val: Vec<u8> = Deserialize::deserialize(deserializer)?;
decode_blob(&val).map_err(D::Error::custom)
}
}
but get the error:
val.into_vec().serialize(serializer)
| ^^^ move occurs because `*val` has type `cdrs::types::blob::Blob`, which does not implement the `Copy` trait
}
Hello @makorne,
You can try val.as_mut_slice().serialize(serializer)
. I think it should work.
However the better way (from my point of view) is to use Vec<u8>
in your structures like the field hash
which you presented. So, after receiving a Blog from a DB you may want to convert it into Vec<u8>
and put the result into your structure.
You can try
val.as_mut_slice().serialize(serializer)
. I think it should work.
Like this?
pub fn deserialize<'de, D>(deserializer: D) -> Result<Blob, D::Error>
where
D: Deserializer<'de>,
{
let mut val: Vec<u8> = Deserialize::deserialize(deserializer)?;
val.as_mut_slice().serialize(serializer);
}
error[E0425]: cannot find value
serializer in this scope
However the better way (from my point of view) is to use
Vec<u8>
in your structures ...
I tried Vec<u8>
at the start.
But got an error:
#[derive(Serialize, Deserialize, Debug, TryFromRow)]
| ^^^^^^^^^^ function or associated item not found in `u8`
Like this?
Yes. But this line val.as_mut_slice().serialize(serializer)
should be in a serializer, shouldn't it?
Ha. I've been trying so long to remove error in deserializer, that was still thinking you wrote me about it some rust kung-fu :) Yes. But changing does not solve the problem.
pub fn serialize<S>(val: &mut Blob, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
val.as_mut_slice().serialize(serializer)
}
#[derive(Serialize, Deserialize, Debug, TryFromRow)]
| ^^^^^^^^^ types differ in mutability
|
= note: expected mutable reference `&mut cdrs::types::blob::Blob`
found reference `&'__a cdrs::types::blob::Blob`
I think you can simplify your life a bit by omitting manual implementation. There is something from Serde team that helps to work with byte arrays. https://github.com/serde-rs/bytes Blob is a Cassandra type that represents a byte array.
So, what you could do is following:
- change
hash: Blob
tohash: Vec<u8>
in yourstruct Data
, - when you put has into
Data
dohash: blob.into_vec()
- add annotation comments according to https://github.com/serde-rs/bytes recomendation.
As I said, I recommend to not use Blob
in your domain data structures and prefer Rust-based types instead of ones from Cassandra domain. For such Rust-based types I'll have more support in libs like Serde and you'll have less manual work. In this case, it means to use Vec<u8>
instead of Blob
.
But as I wrote before, Vec<u8>
was throwing cdrs errors:
54 | #[derive(Serialize, Deserialize, Debug, TryFromRow)]
| ^^^^^^^^^^ function or associated item not found in `u8`
error[E0599]: no function or associated item named `try_from_udt` found for type `u8` in the current scope
What to do with this?
Remove TryFromRow
from #[derive(Serialize, Deserialize, Debug, TryFromRow)]
,
and not use ::try_from_row(row)?
And do its work manually?
@makorne
Please let me check how TryFromRow
works in case if some field is a blob (vector of bytes). I'll get back to you in this issue.
@AlexPikalov Hi, I hope you are ok in our pandemic time?
Any news about blob issue?
Please let me check how
TryFromRow
works in case if some field is a blob (vector of bytes). I'll get back to you in this issue.
Hi @makorne ,
Sorry for quite a late response. The problem cause is in the proc macro that derives TryFromRow
trait. Unfortunately, I was not able to start the work on it.