循环包依赖,同时实施PROC宏

问题描述 投票:3回答:1

我尝试实现proc_macro Dump,这是类似SERDES Serialize

为了这个目的,我有一个箱子foo包含(在这种情况下P1P2)我的“原始”结构,其只应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" }
rust rust-macros rust-proc-macros
1个回答
0
投票

由于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_coreP1

所以我所做的就是:

  • P2删除P1P2并将其付诸foo
  • 去除foo_core依赖foo_dump所以它只取决于foo_derivesyn
  • 添加quotefoo_corefoo的依赖
  • 添加依赖foo_dumpfoo_dump

(你可以看到的变化在foo的完整列表)。

最终的依存关系链,现在看起来是这样的:

© www.soinside.com 2019 - 2024. All rights reserved.