Rust宏-结构体、枚举、转换[已关闭]

mv1qrgav  于 2023-01-05  发布在  其他
关注(0)|答案(1)|浏览(104)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

昨天关门了。
Improve this question
我有问题(也许) rust 宏,或其他一些聪明的方式来实现这一点。
1.以下代码来自第三方,无法修改

pub struct Message0;

pub struct Message1;

pub struct Message {
   pub payload: Option<Payload>,
}

pub enum Payload {
   PayloadMessage0(Message0),
   PayloadMessage1(Message1),
}

pub fn third_party_send(msg: Message) {
   // ...
}

1.期望以某种方式实现该函数(或者不需要为Message0和Message1类型中的每一个实现单独函数的某个其他变体)

pub fn send<T>(specific_msg: T) {
    third_party_send(Message {
        payload: Some(Payload::PayloadMessage???(specific_msg)),
    });
}

我是新来的 rust ,仍然有点困惑的宏和泛型。

92dk7w1h

92dk7w1h1#

我不认为你可以为每个变量创建一个函数,但是你可以创建一个宏来为你做这件事,然后我把它们 Package 在一个trait中,把Message?转换成Payload,并启用你的泛型函数:

pub trait ToPayload {
    fn to_payload(self) -> Payload;
}
macro_rules! to_payload {
    ($message:ident, $payload:ident) => {
        impl ToPayload for $message {
            fn to_payload(self) -> Payload {
                Payload::$payload(self)
            }
        }
    }
}

to_payload!{ Message0, PayloadMessage0 }
to_payload!{ Message1, PayloadMessage1 }

pub fn send<T: ToPayload>(specific_msg: T) {
    third_party_send(Message {
        payload: Some(specific_msg.to_payload())
    });
}

fn main() {
    send(Message0);
    send(Message1);
}

Playground
使用不稳定特性concat_idents,您可以从宏调用中删除一些重复

#![feature(concat_idents)]

macro_rules! to_payload {
    ($message:ident) => {
        impl ToPayload for $message {
            fn to_payload(self) -> Payload {
                use Payload::*;
                concat_idents!(Payload, $message) (self)
            }
        }
    };
}

to_payload! { Message0 }

相关问题