How do I solve this lifetime error for Serde Deserialize? - serialization

Goal: I would like to implement this trait without getting lifetime errors.
Dependencies: pqcrypto-dilithium = "0.4.5" and serde = {version = "1.0.138", features = ["derive"]}. Import this in Cargo.toml
Import:
pub use pqcrypto_dilithium::dilithium5::*;
pub use pqcrypto_dilithium::dilithium5::DetachedSignature;
pub use serde::ser::{SerializeTuple};
pub use serde::de::Visitor;
pub use serde::{Serialize, Serializer, Deserialize, Deserializer};
The Seriaize implementation functions properly but the Deserialization one has lifetime issues.
#[derive(Serialize, Deserialize)]
pub struct Keys {
pub public_key: pqcrypto_dilithium::dilithium5::PublicKey,
pub private_key: pqcrypto_dilithium::dilithium5::SecretKey,
}
impl Serialize for Keys {
fn serialize<S>(&self, serializer: &mut S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut state = serializer.serialize_tuple(2)?;
state.serialize_element(&self.public_key)?;
state.serialize_element(&self.private_key)?;
state.end()
}
}
impl Deserialize<'de> for Keys {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
deserializer.deserialize_tuple(2, Visitor)
}
}
The problem here is in the deserialize implementation for Keys. I am getting this error.
use of undeclared lifetime name `'de`
undeclared lifetimerustcE0261
crypto.rs(36, 5): consider introducing lifetime `'de` here: `<'de>`
crypto.rs(37, 20): consider introducing lifetime `'de` here: `'de, `
[E0261] use of undeclared lifetime name `'de`.
[Note] undeclared lifetime

Correct Answer:
impl <'de> Deserialize<'de> for Keys {
fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
where D: Deserializer<'de>...

Related

How to split an implementation of a trait into multiple files?

I started working with ws, and I would like to split the Handler trait implementation into multiple files.
So I wrote this in one file, on_open.rs:
impl Handler for Client {
fn on_open(&mut self, _: Handshake) -> Result<()> {
println!("Socket opened");
Ok(())
}
}
And this in another file, on_message.rs:
impl Handler for Client {
fn on_message(&mut self, msg: Message) -> Result<()> {
println!("Server got message '{}'. ", msg);
Ok(())
}
}
While compiling it I got the following error:
error[E0119]: conflicting implementations of trait `ws::handler::Handler` for type `models::client::Client`:
--> src\sockets\on_message.rs:9:1
|
9 | impl Handler for Client {
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `models::client::Client`
|
::: src\sockets\on_open.rs:8:1
|
8 | impl Handler for Client {
| ----------------------- first implementation here
I'd like to have the files to be separated so that each developer can work on a separate one. Is there a way to achieve this or am I forced to have the full trait implementation in a single file?
Although you can have multiple impl blocks for the same object, you can't have two which are exactly the same, hence the error of conflicting implementations indicated by E0119:
Since a trait cannot be implemented multiple times, this is an error.
(If the trait could be specialised because it takes any number of generic type arguments the situation would be very much different because every specialisation would be a different impl block. However even then you wouldn't be able to have the same specialisation implemented more than once.)
If you would like to split the functionality into separate files, you could do that, but in a slightly different way than you originally thought. You could split the Client's impl block instead of the Handler implementation as the following minimal and compilable example demonstrates. (Try it in the playground!)
As you can see, the Handler trait is implemented for Client in one place, but all the implementations of Client are split into multiple files/modules and the Handler implementation is just referencing those:
mod handler
{
pub type Result<T> = ::std::result::Result<T, HandlerError>;
pub struct HandlerError;
pub trait Handler
{
fn on_open(&mut self, h: usize) -> Result<()>;
fn on_message(&mut self, m: bool) -> Result<()>;
}
}
mod client
{
use super::handler::{ self, Handler };
struct Client
{
h: usize,
m: bool,
}
impl Handler for Client
{
fn on_open(&mut self, h: usize) -> handler::Result<()>
{
self.handle_on_open(h)
}
fn on_message(&mut self, m: bool) -> handler::Result<()>
{
self.handle_on_message(m)
}
}
mod open
{
use super::super::handler;
use super::Client;
impl Client
{
pub fn handle_on_open(&mut self, h: usize) -> handler::Result<()>
{
self.h = h;
Ok(())
}
}
}
mod message
{
use super::super::handler;
use super::Client;
impl Client
{
pub fn handle_on_message(&mut self, m: bool) -> handler::Result<()>
{
self.m = m;
Ok(())
}
}
}
}
Thanks for #Peter's answer, I re-wrote my code as below, and it is working fine:
socket.rs
use ws::Handler;
use crate::models::client::Client;
use ws::{Message, Request, Response, Result, CloseCode, Handshake};
impl Handler for Client {
fn on_open(&mut self, hs: Handshake) -> Result<()> {
self.handle_on_open(hs)
}
fn on_message(&mut self, msg: Message) -> Result<()> {
self.handle_on_message(msg)
}
fn on_close(&mut self, code: CloseCode, reason: &str) {
self.handle_on_close(code, reason)
}
fn on_request(&mut self, req: &Request) -> Result<(Response)> {
self.handle_on_request(req)
}
}
sockets/on_open.rs
use crate::models::client::Client;
use crate::CLIENTS;
use crate::models::{truck::Truck};
use ws::{Result, Handshake};
impl Client {
pub fn handle_on_open(&mut self, _: Handshake) -> Result<()> {
println!("socket is opened");
Ok(())
}
}

Implement a trait for another trait Item type

I need to convert a parse error to my own Error type while returning Result. Simplified, it looks like the following:
enum MyError {
Parse,
...,
}
fn process<R: FromStr>(s: &str) -> Result<(), MyError> {
Ok(s.parse::<R>()?)
}
For above to work From trait should be implemented. This doesn't work:
impl From<std::str::FromStr::Err> for MyError {
fn from(e: std::str::FromStr::Err) -> MyError {
MyError::Parse
}
}
The compiler diagnostics:
help: use fully-qualified syntax: `<Type as std::str::FromStr>::Err`
But I don't know the exact Type here. The whole point is to allow conversion from all possible errors.
The type FromStr::Err is an associated type of the FromStr trait. Every implementation of FromStr has its own associated type, and this type is completely unconstrained – it could be any type at all. This means you would need a conversion from any type to MyError to achieve what you want:
impl<T> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
However, this implementation is disallowed by the coherence rules – it conflicts with the implementation of From<T> for any type T in the standard library. And even if this implementation was allowed, it wouldn't really do what you want – any error type would be converted to MyError::Parse, not just parse errors.
One possible workaround is to introduce a marker trait for parse error types:
trait ParseError {}
impl<T: ParseError> From<T> for MyError {
fn from(e: T) -> MyError {
MyError::Parse
}
}
You can then implement this marker trait for all parse error types:
impl ParseError for std::str::ParseBoolError {}
impl ParseError for std::num::ParseFloatError {}
impl ParseError for std::num::ParseIntError {}
impl ParseError for std::net::AddrParseError {}
impl ParseError for std::char::ParseCharError {}
If you're discarding the parse error anyway, use map_err to change the error locally:
fn process<R: FromStr>(s: &str) -> Result<(), MyError> {
let _ = s.parse::<R>().map_err(|_| MyError::Parse)?;
Ok(())
}

What is the most idiomatic way to merge two error types?

I have a type Foo whose methods may "raise" errors of an associated type Foo::Err.
pub trait Foo {
type Err;
fn foo(&mut self) -> Result<(), Self::Err>;
}
I have another trait Bar with a method intended to process a Foo. Bar may issue errors of its own (specified by an associated type Bar::Err), but it may also encounter errors generated by the Foo it is processing.
I can see two ways to do this, but I don't know which one would be the most idiomatic to Rust.
The first one embeds a result in a result:
pub trait Bar1 {
type Err;
fn bar<F: Foo>(&mut self, foo: F) -> Result<Result<F, F::Err>, Self::Err>;
}
The second one merges the two error types into a dedicated enum:
pub trait Bar2 {
type Err;
fn bar<F: Foo>(&mut self, foo: F) -> Result<F, Choice<F::Err, Self::Err>>;
}
The second one looks semantically cleaner, but creates some hurdles for handling the additional enum.
playground
Typically you don't do a "merge", but instead use nested errors, like this.
enum IntError {
Overflow,
Underflow
}
enum StrError {
TooLong,
TooShort,
}
enum GenericError {
Int(IntError),
Str(StrError),
}
impl From<IntError> for GenericError {
fn from(e: IntError) -> Self {
GenericError::Int(e)
}
}
impl From<StrError> for GenericError {
fn from(e: StrError) -> Self {
GenericError::Str(e)
}
}
You should use a trait object Error, and you return the first error that you encounter:
pub trait Bar {
fn bar<F: Foo>(&mut self, foo: F) -> Result<F, Box<dyn Error>>;
}
or implement your trait like this:
impl Bar for MyType {
type Err = Box<dyn Error>;
fn bar<F: Foo>(&mut self, foo: F) -> Result<F, Self::Err>;
}
If you really want to have your two errors (but this is strange because one error suffices to make the process not ok), you can use a crate like failure to create an "error trace".
As a general advice, you should not forget to use the traits from std to add more semantic to your code.

How do I use a trait object in a BinaryHeap? [duplicate]

Editor's note: This code example is from a version of Rust prior to 1.0 and is not syntactically valid Rust 1.0 code. Updated versions of this code produce different errors, but the answers still contain valuable information.
It seems like we cannot test for equality in the following case. Why is this? Is there a workaround? (I am using Rust 0.11).
trait A: PartialEq {}
#[deriving(PartialEq)]
enum T {Ta, Tb}
impl A for T {}
fn main() {
assert!(Ta == Ta);
assert!(Ta != Tb);
assert!(some_fn(&Ta, &Ta));
assert!(!some_fn(&Ta, &Tb));
}
fn some_fn(an_a: &A, another_a: &A) -> bool {
an_a == another_a
// ERROR ^~~~~~~~~~~~ binary operation `==` cannot be applied to type `&A`
}
fn another_fn(an_a: &A + PartialEq, another_a: &A + PartialEq) -> bool {
// ERROR: ^~~~~~~~~ only the builtin traits can be used as closure or object bounds
an_a == another_a
}
With help from Vladimir Matveev, I figured out how to use Any to downcast my trait to a concrete type and test the resulting value for equality:
// `Any` allows us to do dynamic typecasting.
use std::any::Any;
trait A {
// An &Any can be cast to a reference to a concrete type.
fn as_any(&self) -> &dyn Any;
// Perform the test.
fn equals_a(&self, _: &dyn A) -> bool;
}
#[derive(Debug, PartialEq)]
enum T {
Ta,
Tb,
}
// Implement A for all 'static types implementing PartialEq.
impl<S: 'static + PartialEq> A for S {
fn as_any(&self) -> &dyn Any {
self
}
fn equals_a(&self, other: &dyn A) -> bool {
// Do a type-safe casting. If the types are different,
// return false, otherwise test the values for equality.
other
.as_any()
.downcast_ref::<S>()
.map_or(false, |a| self == a)
}
}
fn main() {
assert_eq!(T::Ta, T::Ta);
assert_ne!(T::Ta, T::Tb);
assert!(some_fn(&T::Ta, &T::Ta));
assert!(!some_fn(&T::Ta, &T::Tb));
}
fn some_fn(an_a: &dyn A, another_a: &dyn A) -> bool {
// It works!
an_a.equals_a(another_a)
}
Here is the definition of the PartialEq trait:
pub trait PartialEq<Rhs = Self>
where
Rhs: ?Sized,
{
fn eq(&self, other: &Rhs) -> bool;
fn ne(&self, other: &Rhs) -> bool { ... }
}
Note the Self parameter type. This means that eq() and ne() methods accept a parameter of the same type as implementor. For example:
impl PartialEq for i32 {
fn eq(&self, other: &i32) -> bool { ... }
}
impl PartialEq for String {
fn eq(&self, other: &String) -> bool { ... }
}
Note how type of other changes to reflect the type PartialEq is implemented for.
This is the problem. In trait objects, the actual type is erased and unavailable at runtime. This means that it is impossible to obtain a reference to a concrete type from a trait object; in particular, you can't go from &A to &T in your example.
This means that it is impossible to call methods accepting or returning the Self type on trait objects. Indeed, these methods always require a concrete type, but if you have only a trait object, there is no concrete type, and there is no way such method could work in any sensible way.
In certain cases of trait objects, you wish to compare them based on some properties exposed via the trait. You can achieve this by implementing methods on the trait type itself:
trait A {
fn id(&self) -> i32;
}
impl PartialEq for dyn A + '_ {
fn eq(&self, other: &Self) -> bool {
self.id() == other.id()
}
}
impl Eq for dyn A + '_ {}
fn some_fn(an_a: &dyn A, another_a: &dyn A) -> bool {
an_a == another_a
}
This doesn't directly address the original case which wants to delegate back to the implementation of PartialEq of the underlying type, but you can combine the existing solution:
impl PartialEq for dyn A + '_ {
fn eq(&self, other: &Self) -> bool {
self.equals_a(other)
}
}
See also:
Why would I implement methods on a trait instead of as part of the trait?

Implement fmt::Display for Vec<T>

I want to implement the fmt::Display for a nested struct commonly used in my code.
// The root structure
pub struct WhisperFile<'a> {
pub path: &'a str,
pub handle: RefCell<File>,
pub header: Header
}
pub struct Header{
pub metadata: metadata::Metadata,
pub archive_infos: Vec<archive_info::ArchiveInfo>
}
pub struct Metadata {
// SNIP
}
pub struct ArchiveInfo {
// SNIP
}
As you can see, this is a non-trivial tree of data. The archive_infos property on Header can be quite long when presented as one line.
I would like to emit something along the lines of
WhisperFile ({PATH})
Metadata
...
ArchiveInfo (0)
...
ArchiveInfo (N)
...
But when I try to display Vec<ArchiveInfo> I get that Display is not implemented. I can implement fmt::Display for ArchiveInfo but that's not enough since fmt::Display is not implemented for the parent container Vec. If I implement fmt::Display for collections::vec::Vec<ArchiveInfo> I get the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types.
I have tried iterating over the vec and calling write!() but I couldn't figure out what the control flow should look like. I think write!() needs to be return value of the function but that breaks down with multiple calls.
How can I pretty print a Vec of my structures?
As this error states, you cannot implement a trait for a type you don't own:
the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types
However, you can implement Display for your wrapper type. The piece you are missing is to use the try! macro or the try operator ?:
use std::fmt;
struct Foo(Vec<u8>);
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Values:\n")?;
for v in &self.0 {
write!(f, "\t{}", v)?;
}
Ok(())
}
}
fn main() {
let f = Foo(vec![42]);
println!("{}", f);
}