Recursive call of interface implementation in rust language - interface

How do I call recursively an interface I am implementing from the implementation of this interface?
I am doing the following thing:
import io::*;
import to_str::*;
enum some_enum {
foo(~[some_enum]),
bar
}
impl to_str for some_enum {
fn to_str() -> str {
alt self {
bar { "bar" }
foo(nest) { "foo" + nest.to_str() } // this line
}
}
}
fn main() {
println(foo(~[bar,bar,bar]).to_str());
}
And it fails at compile time with
user#note ~/soft/mine/rust $ rustc example.rs && ./example
example.rs:13:32: 13:43 error: failed to find an implementation of interface core::to_str::to_str for some_enum
example.rs:13 foo(nest) { "foo" + nest.to_str() }
^~~~~~~~~~~
Of course I can do an FP-like thing:
foo(nest) { "foo" + nest.map(|x| { x.to_str() }).to_str() }
But why isn't the former case valid?

Seems like it can be solved with using impl of instead of impl.
impl without of acts like interface-less implementation, with no actual interface involved.
(confirming to http://dl.rust-lang.org/doc/tutorial.html#interface-less-implementations )

Related

Is there a way to get generic constraints take in an enum in swift? Or is there a better way to reduce code?

What I want to do is somewhat complicated, pardon all the variable names.
Currently I have been to doing something like
enum Foo {
enum Bar {
case prop11
case prop12
case prop13
// etc
}
enum Baz {
case prop21
case prop22
case prop23
// etc
}
}
protocol Fum1 {
var zot: Foo.Bar { get set }
}
protocol Fum2 {
var zot: Foo.Baz { get set }
}
struct Grunt1: Fum1 {
// code
}
struct Grunt2: Fum2 {
// code
}
This is causing me to duplicate a LOT of code though. Because the same functions can (for the most part) be run on either Grunt1 or Grunt2, and I keep having to specify with something like this
protocol Bletch {
func doSomething(to grunt: Grunt1)
func doSomething(to grunt: Grunt2)
}
But the implementations are the same for both functions. This is quite frustrating. I'd like to do something like
protocol Fum {
associatedType Thud
var zot: Thud { get set }
}
struct Grunt<T: Foo>: Fum {
typealias Thud = T
}
This would then let me do something like
let grunt1 = Grunt<Foo.Bar>(zot: .prop11) //Autocompletes to .prop11, .prop12, .prop13
let grunt2 = Grunt<Foo.Baz>(zot: .prop23) //Autocompletes to .prop23, .prop22, .prop23
Then I could do something like
protocol Bletch {
func doSomething(to grunt: Fum) // or (any Fum), whichever doesn't throw errors.
}
But this doesn't work, Is there a different way of getting the result I'm after? I'm just trying to reduce duplicate code.
Most of what you describe already works except <T: Foo> since Foo is not a protocol.
Instead of making Foo.Bar and Foo.Baz nested types, you can make Foo a protocol and let both Bar and Baz adopt the protocol. (why are they nested types anyways?):
protocol Foo {}
enum Bar : Foo { /* cases */ }
enum Baz : Foo { /* cases */ }
If that's not an option, you can also extend Foo.Bar and Foo.Baz and let them both adopt to a common protocol:
protocol FooProtocol {}
extension Foo.Bar : FooProtocol {}
extension Foo.Baz : FooProtocol {}
Now you just need to constraint your generic T on Grunt to be a FooProtocol instead of Foo:
struct Grunt<T: FooProtocol>: Fum {
typealias Thud = T
var zot: Thud
}

How does one define optional methods on traits?

Does Rust have a feature whereby I can create define potentially non-existent methods on traits?
I realize that Option can be used to handle potentially non-existent properties but I don't know how the same can be achieved with methods.
In TypeScript, the question mark denotes that the methods may potentially be non-existent. Here is an excerpt from RxJs:
export interface NextObserver<T> {
next?: (value: T) => void;
// ...
}
If this feature does not exist in Rust, how should one think about dealing with objects whereby the programmer doesn't know whether a method will be present or not? Panic?
You can try using empty default implementations of methods for this:
trait T {
fn required_method(&self);
// This default implementation does nothing
fn optional_method(&self) {}
}
struct A;
impl T for A {
fn required_method(&self) {
println!("A::required_method");
}
}
struct B;
impl T for B {
fn required_method(&self) {
println!("B::required_method");
}
// overriding T::optional_method with something useful for B
fn optional_method(&self) {
println!("B::optional_method");
}
}
fn main() {
let a = A;
a.required_method();
a.optional_method(); // does nothing
let b = B;
b.required_method();
b.optional_method();
}
Playground

Is it possible to write a macro to generate N enum variants based on a common name? [duplicate]

I'd like to create a setter/getter pair of functions where the names are automatically generated based on a shared component, but I couldn't find any example of macro rules generating a new name.
Is there a way to generate code like fn get_$iden() and SomeEnum::XX_GET_$enum_iden?
If you are using Rust >= 1.31.0 I would recommend using my paste crate which provides a stable way to create concatenated identifiers in a macro.
macro_rules! make_a_struct_and_getters {
($name:ident { $($field:ident),* }) => {
// Define the struct. This expands to:
//
// pub struct S {
// a: String,
// b: String,
// c: String,
// }
pub struct $name {
$(
$field: String,
)*
}
paste::item! {
// An impl block with getters. Stuff in [<...>] is concatenated
// together as one identifier. This expands to:
//
// impl S {
// pub fn get_a(&self) -> &str { &self.a }
// pub fn get_b(&self) -> &str { &self.b }
// pub fn get_c(&self) -> &str { &self.c }
// }
impl $name {
$(
pub fn [<get_ $field>](&self) -> &str {
&self.$field
}
)*
}
}
};
}
make_a_struct_and_getters!(S { a, b, c });
My mashup crate provides a stable way to create new identifiers that works with any Rust version >= 1.15.0.
#[macro_use]
extern crate mashup;
macro_rules! make_a_struct_and_getters {
($name:ident { $($field:ident),* }) => {
// Define the struct. This expands to:
//
// pub struct S {
// a: String,
// b: String,
// c: String,
// }
pub struct $name {
$(
$field: String,
)*
}
// Use mashup to define a substitution macro `m!` that replaces every
// occurrence of the tokens `"get" $field` in its input with the
// concatenated identifier `get_ $field`.
mashup! {
$(
m["get" $field] = get_ $field;
)*
}
// Invoke the substitution macro to build an impl block with getters.
// This expands to:
//
// impl S {
// pub fn get_a(&self) -> &str { &self.a }
// pub fn get_b(&self) -> &str { &self.b }
// pub fn get_c(&self) -> &str { &self.c }
// }
m! {
impl $name {
$(
pub fn "get" $field(&self) -> &str {
&self.$field
}
)*
}
}
}
}
make_a_struct_and_getters!(S { a, b, c });
No, not as of Rust 1.22.
If you can use nightly builds...
Yes: concat_idents!(get_, $iden) and such will allow you to create a new identifier.
But no: the parser doesn't allow macro calls everywhere, so many of the places you might have sought to do this won't work. In such cases, you are sadly on your own. fn concat_idents!(get_, $iden)(…) { … }, for example, won't work.
There's a little known crate gensym that can generate unique UUID names and pass them as the first argument to a macro, followed by a comma:
macro_rules! gen_fn {
($a:ty, $b:ty) => {
gensym::gensym!{ _gen_fn!{ $a, $b } }
};
}
macro_rules! _gen_fn {
($gensym:ident, $a:ty, $b:ty) => {
fn $gensym(a: $a, b: $b) {
unimplemented!()
}
};
}
mod test {
gen_fn!{ u64, u64 }
gen_fn!{ u64, u64 }
}
If all you need is a unique name, and you don't care what it is, that can be useful. I used it to solve a problem where each invocation of a macro needed to create a unique static to hold a singleton struct. I couldn't use paste, since I didn't have unique identifiers I could paste together in the first place.

Sweet.js: Possible to expand a JS object into a JS object?

Is it possible to use Sweet.Js to expand
{ "foo": "bar" }
to
{ "bar": "foo" }
for example?
My naïve attempt here doesn’t work and I don’t see an example in the documentation.
Thanks.
The trick is that : has special meaning in patterns so you need to escape it with $[:]
macro bar {
rule { {$x $[:] $y} } => { {$y: $x} }
}
var o = bar { "bax": "quux" }

How to enforce that a type implements a trait at compile time?

I want to write a macro like this:
macro_rules! a {
( $n:ident, $t:ty ) => {
struct $n {
x: $t
}
}
}
But $t should implement Add, Sub and Mul traits. How can I check it at compile-time?
First, solve the problem without macros. One solution is to create undocumented private functions that will fail compilation if your conditions aren't met:
struct MyType {
age: i32,
name: String,
}
const _: () = {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
// RFC 2056
fn assert_all() {
assert_send::<MyType>();
assert_sync::<MyType>();
}
};
Then, modify the simple solution to use macros:
macro_rules! example {
($name:ident, $field:ty) => {
struct $name {
x: $field,
}
const _: () = {
fn assert_add<T: std::ops::Add<$field, Output = $field>>() {}
fn assert_mul<T: std::ops::Mul<$field, Output = $field>>() {}
// RFC 2056
fn assert_all() {
assert_add::<$field>();
assert_mul::<$field>();
}
};
};
}
example!(Moo, u8);
example!(Woof, bool);
In both cases, we create a dummy const value to scope the functions and their calls, avoiding name clashes.
I would then trust in the optimizer to remove the code at compile time, so I wouldn't expect any additional bloat.
Major thanks to Chris Morgan for providing a better version of this that supports non-object-safe traits.
It's worth highlighting RFC 2056 which will allow for "trivial" constraints in where clauses. Once implemented, clauses like this would be accepted:
impl Foo for Bar
where
i32: Iterator,
{}
This exact behavior has changed multiple times during Rust's history and RFC 2056 pins it down. To keep the behavior we want in this case, we need to call the assertion functions from another function which has no constraints (and thus must always be true).