Because it thinks that From hasn't been implemented.
The only way to get compilation to succeed is to use:
strum = ">= 0.26.3"
strum_macros = ">= 0.26.3"
Why is that? Doesn't my executable decide the appropriate version to be what's listed in its Cargo.toml (0.26.3) and not what's in the lib's Cargo.toml (>= 0.25.0) during the build?
You probably could get it to work by manually telling it which versions to use in your Cargo.toml, but don't bother. Just stop using >= dependency constraints because they work really bad. Your issues will go away if you do that.
hmm.. but then I get a ton of error: failed to select a version for the requirement errors
So instead of >= is it better to just use less specific versions in my lib? Like 0 instead of >= 0.26.0? The problem is for 0.x.x versions the semver rules are a little messy, whereas >= is very straight forward, or so I thought...
The semver rules for 0.x.y are the same as for x.y.z, just shifted to the right; eg by default changing the x is considered incompatible and you should get a seperate installation otherwise it's considered a compatible version.
Here is how Rust interprets semver for 0.x: The meaning of 0.x.y in Cargo.toml is that the version must be at least 0.x.y, and that the version must be less 0.(x+1).0.
You executable gets to decide that and you library gets to decide that, too. Because strum 0.25 and 0.26 are considered incompatible you binary gets version-0.26::strum::ParseError and your library gets version-0.25::strum::ParseError.
These are different types, thus, of course, they couldn't be used together.
Some crates overcome that difference by adding manual dependency (so latest version of foo-0.25 would actually just import foo-0.26 to then provide 0.25 API to clients), but till version 1.0 is reached most crates don't bother with such tricks.
@alice already said something about the inequality feature not being the sharpest. But this just seems completely broken, no?
...And I'm hopping on the semver bandwagon. Inequality expressions were at first my favorite due to their mathematical nature, but this issue has really become a thorn for me...
That combination may result in lib using strum 0.25 or 0.27 while exe uses strum 0.26. Cargo allows multiple versions of a crate to co-exist for as long as they are semver incompatible. So for example strum 0.26.0 and strum 0.27.0 can co-exist, but 0.26.0 and 0.26.1 can't. At the same time Cargo doesn't attempt to reduce the amount of different versions, so if you specify strum = ">= 0.25.0", Cargo will try to use the highest available version (currently 0.27.0) first. However sometimes Cargo is trying to hard to keep using the versions in the lockfile, causing a conflicting version error. Try removing Cargo.lock and building again to solve error: failed to select a version for the requirement error. That won't solve the issue that exe and lib use different versions of strum though. For that you really need to specify strum = "0.26.3" and strum_macros = "0.26.3" for lib too.
There are no conflict. Cargo is happy. It satisfied both requirements: gave 0.27strum to your library (as requested) and also gave 0.26strum to you binary (as requested).
Sure, but that makes it less likely that your library would be happy, after all changes that strum0.25 would be compatible with strum 0.25 is higher than changes of it being compatible with strum0.26
I was wrong here, of course Cargo would pick highest-level version. Sorry for misleading comment.
You told the cargo that you would like both solutions and it picked the one it thinks would be the best, why are you unhappy?
You brought it on yourself. By lying to the cargo. If you want to make sure you binary would be compatible with your library then you either have to have compatible requirements or you can reexport things from your lib and never mix items that you import from strum directly with items that you access through your library.
Cargo ignores leading zeros when determining major-incompatible version, so 0.25, 0.26, and 0.27 are all incompatible.
Cargo does not care about unifying major-incompatible versions. It will pick whatever latest version satisfies the wide-open requirement for this particular crate, and move on. From Cargo's perspective, each major version is like a separate crate (strum v0.25.2 is more like strum25 v1.2.0) where it doesn't have to match any major version of any other dependency. Deduplication happens only for minor.patch versions, separately within major crate version range. So if needlessly duplicated major versions were picked on the first try, they'll stay like that.
The moral of the story is don't use >= or <= in Cargo version requirements, as it doesn't work in as expected. You can only make it work manually with surgery of Cargo.lock or cargo update --precise.
Matching major versions across crates is not well supported. It's better if the crates re-export (pub use strum) their public dependencies when they need users to access the same version.
Keep in mind also that public crates like strum are going to assume they may take breaking changes going from 0.25 to 0.26 or any future versions, so it's never logically correct to use an unbounded range even if the resolver did try to dedupe versions, you're just ensuring your code is going to break at some point in the future.
It sometimes makes sense in npm to declare a dependency on packages that make guarantees that they will first deprecate any breaking changes so it takes 2 major versions for it to actually break, so you have dependencies that are bounded ranges like >= 16.3 && < 19, but I don't think anyone is doing that so explicitly in Rust, likely due to the resolver behavior.
This is almost certainly one of those situations where simpler is better; instead use dependabot or the like to ensure you stay up to date.
my problem was I assumed with inequalities Rust would choose a single version satisfying all inequality constraints for that particular dependency. You have set me straight! Thank you.