-2

how can i have crate that depend on with feature use another version of same crate like below

[features]
serde_1 = ["dep_serde_1"]
serde_1_0_133 = ["dep_serde_1_0_133"]

[dependencies]
dep_serde_1 = { package = "serde", version = "1.0.0", optional = true}
dep_serde_1_0_133 = { package = "serde", version = "1.0.133", optional = true}

my problem is compiler force me to use

use dep_serde_1::*;

except like this

use serde::*;

i just enable one of them at time and in code with cfg(feature = serde_1) i'll chose what code must compile

sorry about my poor English

[Edit]

main idea drive form this problem, for example if my model use actix-0.10 and another crate that use my lib use actix-0.12 it generate compiler error

Herohtar
  • 5,347
  • 4
  • 31
  • 41
Ali Mirghasemi
  • 462
  • 2
  • 7

1 Answers1

2

I'm not quite sure I understand what you want. If you want the name of the crate to be serde in your use statements, you can rename them back:

#[cfg(feature = "dep_serde_1")]
extern crate dep_serde_1 as serde;
#[cfg(feature = "dep_serde_1_0_133")]
extern crate dep_serde_1_0_133 as serde;

// Now you can
use serde::*;

[Edit:] The above takes care of your use of serde, but serde_derive has its own ideas. When you define a struct like

#[derive(Serialize)]
struct Asdf { /* … */ }

serde generates code that looks roughly like this:

const _: () = {
    extern crate serde as _serde;
    #[automatically_derived]
    impl _serde::Serialize for Asdf { /* …

i.e. it ignores the renaming of the serde crate and tries to use the crate by its original name.

You can override this behavior with the crate container attribute:

#[derive(Serialize)]
#[serde(crate = "serde")]
struct Asdf { /* … */ }

which will make the generated code use the serde from the outer namespace:

const _: () = {
    use serde as _serde;
    #[automatically_derived]
    impl serde::Serialize for Asdf {

Note, that mutually exclusive features are not a good idea. If you can, it's better to make one the default and the other to override it.

I'm also not sure your cargo dependencies are actually doing what you want them to. Cargo doesn't allow depending on a crate twice, and if I force dep_serde_1 to =1.0.0 cargo will complain that there is a conflict.

Caesar
  • 6,733
  • 4
  • 38
  • 44
  • thanks for your answer it's good but not working with derive macro ```#[derive(Serialize)]``` and generate error – Ali Mirghasemi Feb 04 '22 at 05:11
  • @AliMirghasemi I edited the answer to explain how to handle that. – Caesar Feb 04 '22 at 09:10
  • Thanks I'll try it, and yes i have default feature for serde but i want let user change version base on need – Ali Mirghasemi Feb 04 '22 at 13:16
  • 1
    I think you're not achieving that, it seems your cargo.toml forces a version ≥1.0.133 no matter which features are selected. Just use a single dependency `serde = "1.0"`. Whatever uses your library can then add `serde` as a dependency itself and specify a precise version, or mess around with `cargo update --precise` to modify the lock file. – Caesar Feb 04 '22 at 13:23
  • good point, i checked cargo ignore bug fix version ```1.0.x``` but if i have two different version like this ```serde = "1.0"``` and ```serde = "0.9"``` this code can work – Ali Mirghasemi Feb 04 '22 at 14:03