How to reuse implementation of From<&str> and From<&String> in Rust? - rust

I have some code like this in my Rust project:
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct FQN<'a>(&'a str);
impl<'a> From<&'a str> for FQN<'a> {
fn from(fqn: &'a str) -> Self {
if fqn.split('.').count() < 2 {
panic!("Invalid FQN: {}", fqn);
}
FQN(fqn)
}
}
impl<'a> From<&'a String> for FQN<'a> {
fn from(fqn: &'a String) -> Self {
if fqn.split('.').count() < 2 {
panic!("Invalid FQN: {}", fqn);
}
FQN(fqn)
}
}
In my case this struct is project-internal and I'm the one constructing strings, so I want it to panic if there's an error (I don't want to return a Result type as in https://doc.rust-lang.org/std/str/trait.FromStr.html).
Is there a way to deduplicate this code so that I do not have to repeat the implementation for both &String and &str?
I tried implementing like this, but then the borrow checker yells that I cannot return a value owned by the current function:
impl<'a, T> From<T> for FQN<'a>
where
T: AsRef<str> + 'a,
{
fn from(fqn: T) -> Self {
let fqn_ref = fqn.as_ref();
if fqn_ref.split('.').count() < 2 {
panic!("Invalid FQN: {}", fqn_ref);
}
FQN(fqn_ref)
}
}
I feel like I'm missing something simple here... any pointers?

You can take a reference:
impl<'a, T> From<&'a T> for FQN<'a>
where
T: AsRef<str>,
{
fn from(fqn: &'a T) -> Self {
let fqn_ref = fqn.as_ref();
if fqn_ref.split('.').count() < 2 {
panic!("Invalid FQN: {}", fqn_ref);
}
FQN(fqn_ref)
}
}
However, I think this is over-engineering, and just calling one impl from the other is fine:
impl<'a> From<&'a str> for FQN<'a> {
fn from(fqn: &'a str) -> Self {
if fqn.split('.').count() < 2 {
panic!("Invalid FQN: {}", fqn);
}
FQN(fqn)
}
}
impl<'a> From<&'a String> for FQN<'a> {
fn from(fqn: &'a String) -> Self {
fqn.as_str().into()
}
}

Related

Generic that could be object of type or reference of type

Given a struct and trait:
// Minimal version of the actual data structure and trait
trait MyTrait {
fn blub(&mut self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn blub(&mut self) {
println!("Blub!");
}
}
I would like to create a struct that can hold an object that implements MyTrait:
impl<T> Foo<T>
where
T: MyTrait,
{
fn new(t: T) -> Self {
Self { t }
}
fn run(&mut self) {
// Execute `blub` of `t`.
// Something like:
self.t.blub();
}
}
So far, that's easy. Now comes the crux: I want to accept both owned and mutably referenced types, like this:
fn main() {
let t0 = MyStruct;
let mut f0 = Foo::new(t0);
f0.run();
let mut t1 = MyStruct;
let mut f1 = Foo::new(&mut t1);
f1.run();
}
The code here of course doesn't work, because &mut MyStruct does not implement MyTrait.
In theory, this should be possible though, because MyTrait::blub takes &mut self, which is compatible with both owned and mutably borrowed types.
This is how far I've come. It works, but has two problems:
It has a pointless second generic
It requires PhantomData
use std::{borrow::BorrowMut, marker::PhantomData};
// Minimal version of the actual data structure and trait
trait MyTrait {
fn blub(&mut self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn blub(&mut self) {
println!("Blub!");
}
}
// Object that shall carry objects OR mutable references of type `MyTrait`
struct Foo<T, U> {
t: T,
_p: PhantomData<U>,
}
impl<T, U> Foo<T, U>
where
T: BorrowMut<U>,
U: MyTrait,
{
fn new(t: T) -> Self {
Self { t, _p: PhantomData }
}
fn run(&mut self) {
self.t.borrow_mut().blub();
}
}
fn main() {
let t0 = MyStruct;
let mut f0 = Foo::new(t0);
f0.run();
let mut t1 = MyStruct;
let mut f1: Foo<_, MyStruct> = Foo::new(&mut t1);
f1.run();
}
Blub!
Blub!
Is there a way to implement this more elegantly?
The only other elegant-ish way I have seen so far is to impl MyTrait for &mut MyStruct. Sadly, I do not own the trait or type, so I cannot do that. Although please tell me if my attempts here are misguided and this entire thing is an XY problem; and the actual thing I should do is to report this problem in said library so they can add that impl.
The simplest way is probably to add another implantation of MyTrait for &mut MyStruct.
impl MyTrait for &mut MyStruct {
fn blub(&mut self) {
println!("Blub!");
}
}
If you dont have access to the struct or trait, you can use an enum to manage the Owned and Borrowed versions and implement Deref/DerefMut to keep the usage of t the same.
enum Container<'a, T> {
Owned(T),
Borrowed(&'a mut T)
}
impl<'a, T: MyTrait> From<T> for Container<'a, T> {
fn from(t: T) -> Self {
Self::Owned(t)
}
}
impl<'a, T: MyTrait> From<&'a mut T> for Container<'a, T> {
fn from(t: &'a mut T) -> Self {
Self::Borrowed(t)
}
}
impl<'a, T> Deref for Container<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
Self::Owned(o) => o,
Self::Borrowed(o) => o
}
}
}
impl<'a, T> DerefMut for Container<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
Self::Owned(o) => o,
Self::Borrowed(o) => o
}
}
}
struct Foo<'a, T> {
t: Container<'a, T>
}
impl<'a, T> Foo<'a, T>
where
T: MyTrait,
{
fn new(t: impl Into<Container<'a, T>>) -> Self {
Self{ t: t.into() }
}
fn run(&mut self) {
self.t.blub();
}
}
Other solutions I found:
This one doesn't require looking at an enum at runtime, it solves types at compile time:
use std::marker::PhantomData;
// Minimal version of the actual data structure and trait
trait MyTrait {
fn blub(&mut self);
}
struct MyStruct;
impl MyTrait for MyStruct {
fn blub(&mut self) {
println!("Blub!");
}
}
trait MyTraitFrom<'a, T> {
fn mytrait_from(value: &'a mut T) -> Self;
}
impl<'a, T: MyTrait> MyTraitFrom<'a, T> for &'a mut T {
fn mytrait_from(value: &'a mut T) -> Self {
value
}
}
impl<'a, T: MyTrait> MyTraitFrom<'a, &'a mut T> for &'a mut T {
fn mytrait_from(value: &'a mut &'a mut T) -> Self {
let value: &'a mut T = value;
value
}
}
struct Foo<T, U> {
t: T,
_p: PhantomData<U>,
}
impl<'a, T: 'a, U: 'a> Foo<T, U>
where
&'a mut U: MyTraitFrom<'a, T>,
U: MyTrait,
{
fn new(t: T) -> Self {
Self { t, _p: PhantomData }
}
fn run(&'a mut self) {
let u: &'a mut U = MyTraitFrom::mytrait_from(&mut self.t);
u.blub();
}
}
fn main() {
let t0 = MyStruct;
let mut f0 = Foo::new(t0);
f0.run();
let mut t1 = MyStruct;
let mut f1 = Foo::new(&mut t1);
f1.run();
}
Blub!
Blub!

Trouble with stricter lifetime requirements when implementing FromIterator for LazyList

I was playing with the code from this answer but the FromIterator impl does not compile any more:
error[E0276]: impl has stricter requirements than trait --> src/lib.rs:184:9
| 184 | fn from_iter<I: IntoIterator<Item = T> + 'a>(itrbl: I) -> LazyList<'a, T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `I: 'a`
For more information about this error, try `rustc --explain E0276`.
The slightly updated code is on the playground.
// only necessary because Box<FnOnce() -> R> doesn't work...
mod thunk {
pub trait Invoke<R = ()> {
fn invoke(self: Box<Self>) -> R;
}
impl<R, F: FnOnce() -> R> Invoke<R> for F {
#[inline(always)]
fn invoke(self: Box<F>) -> R { (*self)() }
}
}
// Lazy is lazily evaluated contained value using the above Invoke trait
// instead of the desire Box<FnOnce() -> T> or a stable FnBox (currently not)...
pub mod lazy {
use crate::thunk::Invoke;
use std::cell::UnsafeCell;
use std::mem::replace;
use std::ops::Deref;
// Lazy is lazily evaluated contained value using the above Invoke trait
// instead of the desire Box<FnOnce() -> T> or a stable FnBox (currently not)...
pub struct Lazy<'a, T: 'a>(UnsafeCell<LazyState<'a, T>>);
enum LazyState<'a, T: 'a> {
Unevaluated(Box<dyn Invoke<T> + 'a>),
EvaluationInProgress,
Evaluated(T),
}
use self::LazyState::*;
impl<'a, T: 'a> Lazy<'a, T> {
#[inline]
pub fn new<F: 'a + FnOnce() -> T>(func: F) -> Lazy<'a, T> {
Lazy(UnsafeCell::new(Unevaluated(Box::new(func))))
}
#[inline]
pub fn evaluated(val: T) -> Lazy<'a, T> {
Lazy(UnsafeCell::new(Evaluated(val)))
}
#[inline(always)]
fn force(&self) {
unsafe {
match *self.0.get() {
Evaluated(_) => {}, // nothing required; already Evaluated
EvaluationInProgress => panic!("Lazy::force called recursively!!!"),
_ => {
let ue = replace(&mut *self.0.get(), EvaluationInProgress);
if let Unevaluated(thnk) = ue {
*self.0.get() = Evaluated(thnk.invoke());
} // no other possiblity!
}
}
}
}
#[inline]
pub fn unwrap<'b>(self) -> T where T: 'b { // consumes the object to produce the value
self.force(); // evaluatate if not evealutated
match { self.0.into_inner() } {
Evaluated(v) => v,
_ => unreachable!() // previous code guarantees never not Evaluated
}
}
}
impl<'a, T: 'a> Deref for Lazy<'a, T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
self.force(); // evaluatate if not evalutated
match *unsafe { &*self.0.get() } {
Evaluated(ref v) => v,
_ => unreachable!(),
}
}
}
}
// LazyList is an immutable lazily-evaluated persistent (memoized) singly-linked list
// similar to lists in Haskell, although here only tails are lazy...
// depends on the contained type being Clone so that the LazyList can be
// extracted from the reference-counted Rc heap objects in which embedded.
pub mod lazylist {
use crate::lazy::Lazy;
use std::rc::Rc;
use std::iter::FromIterator;
use std::mem::{replace, swap};
#[derive(Clone)]
pub enum LazyList<'a, T: 'a + Clone> {
Empty,
Cons(T, RcLazyListNode<'a, T>),
}
pub use self::LazyList::Empty;
use self::LazyList::Cons;
type RcLazyListNode<'a, T> = Rc<Lazy<'a, LazyList<'a, T>>>;
// impl<'a, T:'a> !Sync for LazyList<'a, T> {}
impl<'a, T: 'a + Clone> LazyList<'a, T> {
#[inline]
pub fn singleton(v: T) -> LazyList<'a, T> {
Cons(v, Rc::new(Lazy::evaluated(Empty)))
}
#[inline]
pub fn cons<F>(v: T, cntf: F) -> LazyList<'a, T>
where F: 'a + FnOnce() -> LazyList<'a, T>
{
Cons(v, Rc::new(Lazy::new(cntf)))
}
#[inline]
pub fn head(&self) -> &T {
if let Cons(ref hd, _) = *self {
return hd;
}
panic!("LazyList::head called on an Empty LazyList!!!")
}
#[inline]
pub fn tail<'b>(&'b self) -> &'b Lazy<'a, LazyList<'a, T>> {
if let Cons(_, ref rlln) = *self {
return &*rlln;
}
panic!("LazyList::tail called on an Empty LazyList!!!")
}
#[inline]
pub fn unwrap(self) -> (T, RcLazyListNode<'a, T>) {
// consumes the object
if let Cons(hd, rlln) = self {
return (hd, rlln);
}
panic!("LazyList::unwrap called on an Empty LazyList!!!")
}
#[inline]
fn iter(&self) -> Iter<'a, T> {
Iter(self)
}
}
impl<'a, T: 'a + Clone> Iterator for LazyList<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match replace(self, Empty) {
Cons(hd, rlln) => {
let mut newll = (*rlln).clone();
swap(self, &mut newll); // self now contains tail, newll contains the Empty
Some(hd)
}
_ => None,
}
}
}
pub struct Iter<'a, T: 'a + Clone>(*const LazyList<'a, T>);
impl<'a, T: 'a + Clone> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
unsafe {
if let LazyList::Cons(ref v, ref r) = *self.0 {
self.0 = &***r;
Some(v)
} else {
None
}
}
}
}
impl<'i, 'l, T: 'i + Clone> IntoIterator for &'l LazyList<'i, T> {
type Item = &'i T;
type IntoIter = Iter<'i, T>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, T: 'a + Clone, > FromIterator<T> for LazyList<'a, T> {
fn from_iter<I: IntoIterator<Item = T> + 'a>(itrbl: I) -> LazyList<'a, T> {
let itr = itrbl.into_iter();
#[inline(always)]
fn next_iter<'b, R, Itr>(mut iter: Itr) -> LazyList<'b, R>
where R: 'b + Clone,
Itr: 'b + Iterator<Item = R>
{
match iter.next() {
Some(val) => LazyList::cons(val, move || next_iter(iter)),
None => Empty,
}
}
next_iter(itr)
}
}
}
Unfortunately I've exhausted ideas on how to try and fix this.
The code in the question (though not in the referenced answer, which has since been updated) relies on a soundness bug in older versions of the compiler (#18937) which has since been fixed.
It is not possible to implement FromIterator for LazyList, or indeed for any data structure, by storing the iterator inside the structure. This is because the FromIterator trait allows the implementor (Self) to outlive the iterator type (I::IntoIter). That the compiler ever accepted it was an oversight.
When copying code from the internet, be conscious of the age of the source. This code is also out of date in several other respects, notably:
it uses Rust 2015-style paths
it omits dyn on trait object types
the Invoke workaround is no longer needed, since dyn FnOnce() -> T works properly now.

How to define a Vec in Rust to support containing multiple types of structs that implement a same trait?

In c++, I can define a parent class, and the type in vector can just be the father class type. So how to implement that in Rust?
Like for this example:
I defined two types of Integer who both implement the trait Object, now I want to put them in a same vector, is there any way to achieve that?
pub trait Object<T: Object<T>+Clone> {
fn sub(&self, x: &T) -> T {
x.clone() //this is a useless implementation, just for structs don't need to implement this method.
}
}
#[derive(Debug, Copy, Clone)]
pub struct Integer {
val: i32
}
impl Integer {
pub fn get(&self) -> i32 {
self.val
}
pub fn new(val: i32) -> Self {
Integer {
val
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct Int {
val: i32
}
impl Int {
pub fn get(&self) -> i32 {
self.val
}
pub fn new(val: i32) -> Self {
Int {
val
}
}
}
impl Object<Int> for Int {
fn sub(&self, rhs: &Int) -> Int {
Int {
val: self.val - rhs.get()
}
}
}
impl Object<Integer> for Integer {
fn sub(&self, rhs: &Integer) -> Integer {
Integer {
val: self.val - rhs.get()
}
}
}
fn main() {
let mut v: Vec<Box<dyn Object>> = Vec::new();
v.push(Box::new(Integer::new(1)));
v.push(Box::new(Int::new(2)));
}
Thanks a lot.
There are several aspects of your design that don't fit in Rust:
trait Object<T: Object<T>+Clone> doesn't help - Rust doesn't do CRTP, just use Self instead.
for Object to be object-safe (necessary to put it in a vector), it can't be parameterized by type. A type parameter means you get a completely separate trait for each type.
Object::sub() can't return the result by value, because the size of the value can differ for different implementations, so it wouldn't be object-safe. It must return Box<dyn Object> instead.
The code modified as indicated looks like this:
pub trait Object {
fn get(&self) -> i32;
fn sub(&self, x: &dyn Object) -> Box<dyn Object>;
}
#[derive(Debug, Copy, Clone)]
pub struct Integer {
val: i32,
}
impl Integer {
fn new(val: i32) -> Box<dyn Object> {
Box::new(Int { val })
}
}
impl Object for Integer {
fn get(&self) -> i32 {
self.val
}
fn sub(&self, rhs: &dyn Object) -> Box<dyn Object> {
Integer::new(self.val - rhs.get())
}
}
#[derive(Debug, Copy, Clone)]
pub struct Int {
val: i32,
}
impl Int {
fn new(val: i32) -> Box<dyn Object> {
Box::new(Int { val })
}
}
impl Object for Int {
fn get(&self) -> i32 {
self.val
}
fn sub(&self, rhs: &dyn Object) -> Box<dyn Object> {
Int::new(self.val - rhs.get())
}
}
fn main() {
let mut v: Vec<Box<dyn Object>> = vec![];
v.push(Integer::new(1));
v.push(Int::new(2));
v.push(v[0].sub(v[1].as_ref()));
for o in &v {
println!("{}", o.get());
}
}
Playground
I think you can combine trait and provide a blank implementation, then use that in vector
trait TraitA {}
trait TraitB {}
trait CombinedTraitATraitB: TraitA + TraitB {}
impl<T> CombinedTraitATraitB for T where T: TraitA + TraitB {}
let vector: Vec<Box<dyn CombinedTraitATraitB>> = vec![];

thread 'main' has overflowed its stack in Rust

I'm trying to learn Rust (I come from Java) and I'm having some problems.
I'm building a simple program that is the base for a connection pool.
When I run it, I get the runtime error thread 'main' has overflowed its stack and I cannot understand why.
here is main.rs
use hello_rust::concurrent_bag;
use hello_rust::concurrent_bag::BagEntry;
fn main() {
let my_bagentry = BagEntry::new(String::from("ciao"));
//println!("{}", my_bagentry.value());
let mut contVec : Vec<BagEntry<String>>=vec![];
contVec.push(my_bagentry);
println!("state ={}", contVec[0]);
println!("state ={}", contVec[0].value());
let mut my_bag: concurrent_bag::ConcurrentBag<String> =concurrent_bag::ConcurrentBag::new();
my_bag.addEntry(String::from("ciao Entry"));
let result = my_bag.borrowEntry();
if result.is_some() {
println!("{}", result.unwrap().value());
}
}
and here is lib.rs
pub mod concurrent_bag {
use crate::concurrent_bag::BagEntryState::UNUSED;
pub enum BagEntryState {
UNUSED, USED, REMOVED
}
impl fmt::Display for BagEntryState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
BagEntryState::UNUSED => write!(f, "UNUSED"),
BagEntryState::USED => write!(f, "USED"),
BagEntryState::REMOVED => write!(f, "REMOVED"),
}
}
}
impl PartialEq for BagEntryState {
fn eq(&self, other: &Self) -> bool {
self == other
}
}
pub struct BagEntry< T: std::cmp::PartialEq + fmt::Display> {
state : BagEntryState,
value: T,
}
impl<'a, T: std::cmp::PartialEq + fmt::Display> BagEntry<T> {
pub fn new(value: T) -> BagEntry< T> {
BagEntry {
value,
state: UNUSED,
}
}
pub fn value(&self)->&T {
&self.value
}
pub fn state(&self)->&BagEntryState {
&self.state
}
}
impl<'a, T: std::cmp::PartialEq + fmt::Display> PartialEq for BagEntry<T> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: std::cmp::PartialEq + fmt::Display> fmt::Display for BagEntry<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.value)
}
}
use std::sync::Arc;
use core::fmt;
pub struct ConcurrentBag<T: std::cmp::PartialEq + fmt::Display> {
entry_list:Vec<BagEntry<T>>,
}
impl<'a, T: std::cmp::PartialEq + fmt::Display> ConcurrentBag<T> {
pub fn new() -> ConcurrentBag<T> {
ConcurrentBag {
entry_list: vec![],
}
}
pub fn borrowEntry(&self) -> Option<BagEntry<T>> {
println!("borrow vc size {}", self.entry_list.len());
println!("value ={}", (self).entry_list[0].value());
println!("state ={}", (self).entry_list[0].state());
if (self).entry_list[0].state()==&UNUSED {
}
let result:Option<BagEntry<T>> =None;
result
}
pub fn addEntry(&mut self, value: T) {
let my_bagentry = BagEntry::new(value);
(*self).entry_list.push(my_bagentry);
println!("addEntry vc size {}", self.entry_list.len())
}
pub fn removeEntry(&mut self, value: T) {
let my_bagentry = BagEntry::new(value);
let index =(*self).entry_list.iter().position(|x| *x == my_bagentry).unwrap();
self.entry_list.remove(index);
}
}
}
The problematic line is
if (self).entry_list[0].state()==&UNUSED
and I can't undestrand why since the line
println!("state ={}", (self).entry_list[0].state());
seems to work well.
Another issue that puzzles me is that if I use &self in borrowEntry I should use *self for getting access to entry_list but the program compiles and runs without errors.
Doesn't this code repeat itself forever?
impl PartialEq for BagEntryState {
fn eq(&self, other: &Self) -> bool {
self == other
}
}
We implement PartialEq to make it possible to compare instances of a type with == and != operators. So, it doesn't make sense to use self == other in there.
You can just derive PartialEq.
#[derive(PartialEq)]
pub enum BagEntryState {
UNUSED,
USED,
REMOVED,
}
Or, if you want to implement it by hand, you can do something like this.
impl PartialEq for BagEntryState {
fn eq(&self, other: &BagEntryState) -> bool {
match (self, other) {
(&BagEntryState::UNUSED, &BagEntryState::UNUSED)
| (&BagEntryState::USED, &BagEntryState::USED)
| (&BagEntryState::REMOVED, &BagEntryState::REMOVED) => true,
_ => false,
}
}
}

Cannot call a fn<T: X> from an impl<T: X> because X is not satisfied for T

I have a trait RawFd that is implemented for each type that satisfies special requirements.
Now I have a function that accepts any type that implements RawFd. And I have a trait with an implementation for each T that implements RawFd.
However I cannot call my function from my trait even if T implements RawFd:
pub trait RawFd {
fn raw_fd(&self) -> u64;
}
#[cfg(unix)]
impl<T: std::os::unix::io::AsRawFd> RawFd for T {
fn raw_fd(&self) -> u64 { self.as_raw_fd() as u64 }
}
#[cfg(windows)]
impl<T: std::os::windows::io::AsRawSocket> RawFd for T {
fn raw_fd(&self) -> u64 { self.as_raw_socket() as u64 }
}
fn print_fd<T: RawFd>(p: T) {
println!("{}", p.raw_fd());
}
trait Printable {
fn print(&self);
}
impl<T: RawFd> Printable for T {
fn print(&self) {
print_fd(self);
}
}
What is my mistake here and how can I solve it.
(Link to playground)
If you expect to use print_fd() with a reference you must do this:
fn print_fd(p: &impl RawFd) {
println!("{}", p.raw_fd());
}
or
fn print_fd<T: RawFd>(p: &T) {
println!("{}", p.raw_fd());
}
Or you must take self by value:
impl<T: RawFd> Printable for T {
fn print(self) {
print_fd(self);
}
}
Or you could use clone:
impl<T> Printable for T where T: Clone + RawFd {
fn print(&self) {
print_fd(self.clone());
}
}

Resources