我尝试实现proc_macro Dump
,这是类似SERDES Serialize
。
为了这个目的,我有一个箱子foo
包含(在这种情况下P1
和P2
)我的“原始”结构,其只应dumpable。
接下来我有一个foo_derive
箱包含程序的宏本身。
因为我想支持多种格式我的第三个箱子foo_dump
包含Dump
的特征定义(如该结构可转储)和Dumper
(这是后话了后端应该实现)。非常简单的,直到这一点。
当我现在要编译它,我得到这个错误:
$ cargo build
error: cyclic package dependency: package `foo v0.1.0 (/tmp/tmp.u34pI5J6qd/example/foo)` depends on itself. Cycle:
package `foo v0.1.0 (/tmp/tmp.u34pI5J6qd/example/foo)`
... which is depended on by `foo_dump v0.1.0 (/tmp/tmp.u34pI5J6qd/example/foo_dump)`
... which is depended on by `foo_derive v0.1.0 (/tmp/tmp.u34pI5J6qd/example/foo_derive)`
我不知道正确的方法是什么,如何在这个箱子使用的依赖。我目前的一个是:
这当然是不可能的。
我在想什么?我有什么做打破依赖圈?
(Qazxswpoi)
/cargo.to ml
mcve@github
/foo/cargo.to ml
[workspace]
members = [
"foo",
"foo_derive",
"foo_dump",
]
/foo/双人床/礼拜.人生
[package]
name = "foo"
version = "0.1.0"
edition = "2018"
[dependencies]
foo_derive = { path = "../foo_derive" }
/foo_dump/cargo.to ml
use foo_derive::Dump;
struct P1;
struct P2;
#[derive(Dump)]
struct Bar {
primitive_one: P1,
primitive_two: P2,
}
/foo_dump/双人床/礼拜.人生
[package]
name = "foo_dump"
version = "0.1.0"
edition = "2018"
[dependencies]
foo = { path = "../foo" }
/foo_derive/cargo.to ml
use foo::{P1, P2};
pub trait Dumper {
fn dump_p1(&mut self, value: &P1);
fn dump_p2(&mut self, value: &P2);
}
pub trait Dump {
fn dump<D: Dumper>(&self, d: D);
}
impl Dump for P1 {
fn dump<D: Dumper>(&self, d: D) {
d.dump_p1(self);
}
}
impl Dump for P2 {
fn dump<D: Dumper>(&self, d: D) {
d.dump_p2(self);
}
}
/foo_derive/双人床/礼拜.人生
[package]
name = "foo_derive"
version = "0.1.0"
edition = "2018"
[lib]
proc-macro = true
[dependencies]
syn = "*"
quote = "*"
foo_dump = { path = "../foo_dump" }
由于extern crate proc_macro;
use quote::quote;
use proc_macro::TokenStream;
use syn::DeriveInput;
#[proc_macro_derive(Dump)]
pub fn derive_dump(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as DeriveInput);
let name = &input.ident;
quote!(
impl foo_dump::Dump for #name {
fn dump<D: foo_dump::Dumper>(&self, d: D) {
unimplemented!()
}
}
).into()
}
和他的帮助@Boiethious comment我能拿出一个解决方案,这involes引入一个新的箱子in chat其中包含了结构foo_core
和P1
。
所以我所做的就是:
P2
删除P1
和P2
并将其付诸foo
foo_core
依赖foo_dump
所以它只取决于foo_derive
和syn
了quote
在foo_core
和foo
的依赖foo_dump
到foo_dump
(你可以看到的变化在foo
的完整列表)。
最终的依存关系链,现在看起来是这样的: