I am trying to make primitive types and object types by adding the new method to usize:
impl usize {
fn new(value: &u32) -> usize {
value as usize
}
}
I have no idea about what the message tries to say:
error[E0390]: only a single inherent implementation marked with `#[lang = "usize"]` is allowed for the `usize` primitive
--> src/lib.rs:1:1
|
1 | / impl usize {
2 | | fn new(value: &u32) -> usize {
3 | | value as usize
4 | | }
5 | | }
| |_^
|
help: consider using a trait to implement these methods
--> src/lib.rs:1:1
|
1 | / impl usize {
2 | | fn new(value: &u32) -> usize {
3 | | value as usize
4 | | }
5 | | }
| |_^
You can't directly implement methods on types outside of your own crate. However, as the help message says, you can define a new trait and then implement it:
pub trait NewFrom<T> {
fn new(value: T) -> Self;
}
impl NewFrom<&u32> for usize {
fn new(value: &u32) -> Self {
*value as usize
}
}
Still, this is a bit of an odd thing to do. Usually you would just use the built-in conversion:
let int: u32 = 1;
let size = int as usize;
Related
I want to extend primitive numbers in Rust with a floor_nearest method which floors a number to the nearest multiple of another number e.g.:
let x = 3.7.floor_nearest(0.2);
assert_eq!(x, 3.6)
I want to implement this both for all integers and all floats. I have noticed the num_traits crate provides traits Num, Float, and PrimInt. Since the implementation for floats and integers are different, I then set out to make a trait, Rounder, which I would then implement for each numerical trait:
pub trait Rounder
where
Self: Num,
{
fn floor_nearest(self, nearest: Self) -> Self;
}
impl<T> Rounder for T
where
T: Float,
{
fn floor_nearest(self, nearest: Self) -> Self {
(self / nearest).floor() * nearest
}
}
impl<T> Rounder for T
where
T: PrimInt,
{
fn floor_nearest(self, nearest: Self) -> Self {
(self / nearest) * nearest
}
}
However, I get the following error:
error[E0119]: conflicting implementations of trait `math::Rounder`
--> src/math.rs:26:1
|
17 | / impl<T> Rounder for T
18 | | where
19 | | T: Float,
20 | | {
... |
23 | | }
24 | | }
| |_- first implementation here
25 |
26 | / impl<T> Rounder for T
27 | | where
28 | | T: PrimInt,
29 | | {
... |
32 | | }
33 | | }
| |_^ conflicting implementation
I understand the reason for this is technically that a struct could implement both "Float" and "PrimInt", however I know this to not be the case here.
How could I solve this in a sane way that will still allow me to use these implementations as method calls, without duplicating the same code twice for f32 and f64``` and a number of times for the primitive integers?
You can use a macro to implement the trait for all number types:
macro_rules! impl_rounder_for_int {
($($t:ty),*) => {
$(
impl Rounder for $t {
fn floor_nearest(self, nearest: Self) -> Self {
(self / nearest) * nearest
}
}
)*
};
}
impl_rounder_for_int!(i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize);
macro_rules! impl_rounder_for_float {
($($t:ty),*) => {
$(
impl Rounder for $t {
fn floor_nearest(self, nearest: Self) -> Self {
(self / nearest).floor() * nearest
}
}
)*
};
}
impl_rounder_for_float!(f32, f64);
You can make the macro more compact (as #eggyal suggested), however I feel this is a good middle ground between readability and compactness.
This question already has answers here:
Conflicting trait implementations even though associated types differ
(2 answers)
Closed 9 months ago.
I am trying to write a conversion trait that can take both Iterators to references and Iterators to mutable references.
Sadly, it seems that once you implement a trait for Iter<&>, you cannot implement the trait also for Iter<&mut> as they seem to collide. Which doesn't make sense, though, because Iter<&mut> doesn't seem to be able to utilize the implementation for Iter<&>.
Here is a minimal example:
// A dummy object
#[derive(Debug)]
struct MyObj(i32);
// A collection of MyObj references
#[derive(Debug)]
struct RefVec<'a>(Vec<&'a MyObj>);
// Goal: create a conversion function that can take *either* a `Iterator<&MyObj>` *or* `Iterator<&mut MyObj>`.
// Attempt: Create a Conversion Trait and implement it for both of those types
trait ConvertToRefVec<'a> {
fn convert(&mut self) -> RefVec<'a>;
}
// Implement the conversion for Iter<&MyObj>
impl<'a, T> ConvertToRefVec<'a> for T
where
T: Iterator<Item = &'a MyObj>,
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
// Problem: the impl above does not apply to Iter<&mut MyObj>. But the attempt to write an impl
// for Iter<&mut MyObj> fails with the message that it collides with the impl above:
impl<'a, T> ConvertToRefVec<'a> for T
where
T: Iterator<Item = &'a mut MyObj>,
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
fn main() {
let owned = [MyObj(42), MyObj(69)];
let ref_vec = owned.iter().convert();
println!("{:?}", ref_vec);
let ref_vec = owned.iter_mut().convert();
println!("{:?}", ref_vec);
}
Which gives me:
error[E0119]: conflicting implementations of trait `ConvertToRefVec<'_>`
--> src/main.rs:27:1
|
16 | / impl<'a, T> ConvertToRefVec<'a> for T
17 | | where
18 | | T: Iterator<Item = &'a MyObj>,
19 | | {
... |
22 | | }
23 | | }
| |_- first implementation here
...
27 | / impl<'a, T> ConvertToRefVec<'a> for T
28 | | where
29 | | T: Iterator<Item = &'a mut MyObj>,
30 | | {
... |
33 | | }
34 | | }
| |_^ conflicting implementation
But if I leave out the impl for Iterator<&mut>, then I get this error:
error[E0599]: the method `convert` exists for struct `std::slice::IterMut<'_, MyObj>`, but its trait bounds were not satisfied
--> src/main.rs:42:36
|
42 | let ref_vec = owned.iter_mut().convert();
| ^^^^^^^ method cannot be called on `std::slice::IterMut<'_, MyObj>` due to unsatisfied trait bounds
|
::: /home/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/iter.rs:187:1
|
187 | pub struct IterMut<'a, T: 'a> {
| -----------------------------
| |
| doesn't satisfy `<_ as Iterator>::Item = &MyObj`
| doesn't satisfy `std::slice::IterMut<'_, MyObj>: ConvertToRefVec`
|
note: trait bound `<std::slice::IterMut<'_, MyObj> as Iterator>::Item = &MyObj` was not satisfied
--> src/main.rs:18:17
|
16 | impl<'a, T> ConvertToRefVec<'a> for T
| ------------------- -
17 | where
18 | T: Iterator<Item = &'a MyObj>,
| ^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
So my question is: How can I write such a conversion mechanism that works with both Iterator<Item = &MyObj> and Iterator<Item = &mut MyObj?
The thing is that you are trying to implement your trait in two different ways for the same type. So the problem that you treat T as the same one. Then you can just split the cases for concrete types. Like to following:
#[derive(Debug)]
struct MyObj(i32);
#[derive(Debug)]
struct RefVec<'a>(Vec<&'a MyObj>);
trait ConvertToRefVec<'a> {
fn convert(&mut self) -> RefVec<'a>;
}
impl<'a> ConvertToRefVec<'a> for std::slice::Iter<'a, MyObj>
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.collect::<Vec<_>>())
}
}
impl<'a> ConvertToRefVec<'a> for std::slice::IterMut<'a, MyObj>
{
fn convert(&mut self) -> RefVec<'a> {
RefVec(self.map(|el| &*el).collect::<Vec<&MyObj>>())
}
}
fn main() {
let mut owned = [MyObj(42), MyObj(69)];
let ref_vec = owned.iter().convert();
println!("{:?}", ref_vec);
let ref_vec = owned.iter_mut().convert();
println!("{:?}", ref_vec);
}
I am trying to make primitive types and object types by adding the new method to usize:
impl usize {
fn new(value: &u32) -> usize {
value as usize
}
}
I have no idea about what the message tries to say:
error[E0390]: only a single inherent implementation marked with `#[lang = "usize"]` is allowed for the `usize` primitive
--> src/lib.rs:1:1
|
1 | / impl usize {
2 | | fn new(value: &u32) -> usize {
3 | | value as usize
4 | | }
5 | | }
| |_^
|
help: consider using a trait to implement these methods
--> src/lib.rs:1:1
|
1 | / impl usize {
2 | | fn new(value: &u32) -> usize {
3 | | value as usize
4 | | }
5 | | }
| |_^
You can't directly implement methods on types outside of your own crate. However, as the help message says, you can define a new trait and then implement it:
pub trait NewFrom<T> {
fn new(value: T) -> Self;
}
impl NewFrom<&u32> for usize {
fn new(value: &u32) -> Self {
*value as usize
}
}
Still, this is a bit of an odd thing to do. Usually you would just use the built-in conversion:
let int: u32 = 1;
let size = int as usize;
I'm trying to create a fast, flexible and convenient API that accepts an optional string parameter. I wish the user to be able to pass:
None
"foo"
"foo".to_string()
Some("foo") (equivalent to "foo")
Some("foo".to_string()) (equivalent to "foo".to_string())
As far as I know, the best solution to handle "foo" or "foo".to_string() is Into<Cow<'a, str>>. On the other hand, the best solution to handle "foo" or Some("foo") is Into<Option<&'a str>>.
Thus I tried with this but it doesn't compile:
fn foo<'a, T, O>(_bar: O)
where
T: Into<Cow<'a, str>>,
O: Into<Option<T>>,
foo(Some("aaa"));
error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::borrow::Cow<'_, str>>`
--> src/main.rs:12:5
|
12 | foo(Some("aaa"));
| ^^^
|
note: required by `foo`
--> src/main.rs:3:1
|
3 | / fn foo<'a, T, O>(_bar: O)
4 | | where
5 | | T: Into<Cow<'a, str>>,
6 | | O: Into<Option<T>>,
7 | | {}
| |__^
Playground
Is it possible to make it work?
I'm pretty sure you cannot create a function like this and still have it be ergonomically used. The problem is that there can be zero, one, or multiple potential paths through the generic types:
+-----------+
| |
+---------> Option<B> +----------------------+
| | | |
+-+-+ +-----------+ +-----------v----------+
| | | |
| A | | Option<Cow<'a, str>> |
| | | |
+-+-+ +-----------+ +-----------^----------+
| | | |
+---------> Option<C> +----------------------+
| |
+-----------+
That's why you are getting the error you are: It's unclear what the concrete type of T should be, thus the caller would have to provide it to the compiler. Here I use the turbofish:
foo::<&str, _>(Some("aaa"));
foo::<String, _>(Some("aaa".to_string()));
foo::<&str, Option<&str>>(None);
I'd suggest re-evaluating your API design. Possible directions include:
Creating a custom struct and implementing From for specific concrete types (e.g. &str, Option<String>, etc.). Passing None will still have the problem because it's unclear what type of None it is: an Option<&str> or Option<String>?
use std::borrow::Cow;
fn foo<'a, C>(_bar: C)
where
C: Into<Config<'a>>,
{
}
struct Config<'a>(Option<Cow<'a, str>>);
impl<'a> From<&'a str> for Config<'a> {
fn from(other: &'a str) -> Config<'a> {
Config(Some(other.into()))
}
}
impl From<String> for Config<'static> {
fn from(other: String) -> Config<'static> {
Config(Some(other.into()))
}
}
impl<'a> From<Option<&'a str>> for Config<'a> {
fn from(other: Option<&'a str>) -> Config<'a> {
Config(other.map(Into::into))
}
}
impl From<Option<String>> for Config<'static> {
fn from(other: Option<String>) -> Config<'static> {
Config(other.map(Into::into))
}
}
fn main() {
foo("aaa");
foo("aaa".to_string());
foo(Some("aaa"));
foo(Some("aaa".to_string()));
foo(None::<&str>);
}
Switch to a builder pattern — my preferred direction:
use std::borrow::Cow;
#[derive(Debug, Clone, Default)]
struct Foo<'a> {
name: Option<Cow<'a, str>>,
}
impl<'a> Foo<'a> {
fn new() -> Self {
Self::default()
}
fn name<S>(mut self, name: S) -> Self
where
S: Into<Cow<'a, str>>,
{
self.name = Some(name.into());
self
}
fn go(self) {
println!("The name is {:?}", self.name)
}
}
fn main() {
Foo::new().go();
Foo::new().name("aaa").go();
Foo::new().name("aaa".to_string()).go();
}
Note that this removes the need for the caller to specify Some at all; using the name function implies presence. You could make a without_name function to set it back to None if needed.
See also:
Pass None into a function that accepts Option
Create a generic struct with Option<T> without specifying T when instantiating with None
I'm attempting to write a streaming, pipelined server with a non-default tick() method in the transport. I thought this would do it:
use std::io;
use mio::net::TcpListener;
use tokio_core::reactor::PollEvented;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;
use codec::PacketCodec;
type GearmanIO = PollEvented<TcpListener>;
type GearmanFramed = Framed<GearmanIO, PacketCodec>;
impl Transport for GearmanFramed {
fn tick(&mut self) {
trace!("tick!");
}
fn cancel(&mut self) -> io::Result<()> {
trace!("cancel!");
}
}
But, trying to build this file yields this:
error[E0119]: conflicting implementations of trait `tokio_proto::streaming::pipeline::Transport` for type `tokio_io::codec::Framed<tokio_core::reactor::PollEvented<mio::net::TcpListener>, codec::PacketCodec>`:
--> src/transport.rs:14:1
|
14 | / impl Transport for GearmanFramed
15 | | {
16 | | fn tick(&mut self) {
17 | | trace!("tick!");
... |
22 | | }
23 | | }
| |_^
|
= note: conflicting implementation in crate `tokio_proto`
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/transport.rs:14:1
|
14 | / impl Transport for GearmanFramed
15 | | {
16 | | fn tick(&mut self) {
17 | | trace!("tick!");
... |
22 | | }
23 | | }
| |_^ impl doesn't use types inside crate
|
= note: the impl does not reference any types defined in this crate
= note: define and implement a trait or new type instead
I would have expected that the specific nature of GearmanFramed would allow me to implement the Transport trait due to "specialization", but this one is still conflicting with the default, which is here:
use tokio_io as new_io;
// ...
impl<T, C> Transport for new_io::codec::Framed<T,C>
where T: new_io::AsyncRead + new_io::AsyncWrite + 'static,
C: new_io::codec::Encoder<Error=io::Error> +
new_io::codec::Decoder<Error=io::Error> + 'static,
{}
So after a few days of struggling, I figured this out. The answer is to use a newtype to surround Framed, thus avoiding the default implementation.
use std::io;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::codec::{Framed, Encoder, Decoder};
use tokio_proto::streaming::pipeline::Transport;
use futures::{Poll, Sink, StartSend, Stream};
use codec::PacketCodec;
pub struct GearmanFramed<T>(pub Framed<T, PacketCodec>);
impl<T> Transport for GearmanFramed<T>
where T: AsyncRead + AsyncWrite + 'static
{
fn tick(&mut self) {
trace!("tick!");
}
fn cancel(&mut self) -> io::Result<()> {
trace!("cancel!");
Ok(())
}
}
impl<T> Stream for GearmanFramed<T>
where T: AsyncRead
{
type Item = <PacketCodec as Decoder>::Item;
type Error = <PacketCodec as Decoder>::Error;
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
self.0.poll()
}
}
impl<T> Sink for GearmanFramed<T>
where T: AsyncWrite
{
type SinkItem = <PacketCodec as Encoder>::Item;
type SinkError = <PacketCodec as Encoder>::Error;
fn start_send(&mut self, item: Self::SinkItem) -> StartSend<Self::SinkItem, Self::SinkError> {
self.0.start_send(item)
}
fn poll_complete(&mut self) -> Poll<(), Self::SinkError> {
self.0.poll_complete()
}
fn close(&mut self) -> Poll<(), Self::SinkError> {
self.0.close()
}
}