Conversation
Still some doctests(and tests?) FAIL `cargo build --no-default-features` [no ci]
`cargo test --no-default-features` BUT a lot of `#[cfg(feature = "std")]` etc [no ci]
- `cargo test --no-default-features --features=alloc` -> OK - `cargo +nightly-2022-10-22 no-std-check --no-default-features` -> FAIL
- `cargo +nightly-2022-10-22 no-std-check --no-default-features --features=alloc` OK - `cargo test --no-default-features --features=alloc` OK
There was a problem hiding this comment.
Seems actually smaller than expected. Without regards to the fundamental issue with the ImageDecoder trait, it seems almost quite feasible to do in single major version.
Except: Getting rid of/bounding DynamicImage to std is quite a deal breaker for adoption. It would seem that an alloc-but-no_std should be capable of preserving the type, or not?
src/image.rs
Outdated
| #[cfg(feature = "std")] | ||
| type Reader: std::io::Read + 'a; | ||
| #[cfg(not(feature = "std"))] | ||
| type Reader: 'a; |
There was a problem hiding this comment.
These constraints are not compatible but features should be additives. In particular, an impl written without the feature should still compile with the feature since features may be activated by unrelated third-party crates and are thus shared. This fundamentally can not be written like it is here.
Unless prove of the opposite, i'd assume that whatever magic is necessary to change the behavior, it must happen within the trait bound while keeping the same trait bound in both cases.
There was a problem hiding this comment.
I'd be OK with just limiting ImageDecoder to std. All the implementations have a constructor that takes a io::Read so there's going to be little use for it in no_std settings
There was a problem hiding this comment.
I don't think I have gated ImageDecoder behind std. Technically, only its impl using Reader are?
There was a problem hiding this comment.
What I was saying is that ImageDecoder should be gated behind std. Because it isn't useful in a no_std context, not just because some of its associated types / methods require standard library traits.
src/error.rs
Outdated
| #[derive(Snafu, Debug)] | ||
| pub enum ImageError { | ||
| /// An error was encountered while decoding. | ||
| /// | ||
| /// This means that the input data did not conform to the specification of some image format, | ||
| /// or that no format could be determined, or that it did not match format specific | ||
| /// requirements set by the caller. | ||
| Decoding(DecodingError), | ||
| /// | ||
| /// An error was encountered while decoding an image. | ||
| /// | ||
| /// This is used as an opaque representation for the [`ImageError::Decoding`] variant. See its | ||
| /// documentation for more information. | ||
| /// | ||
| /// [`ImageError::Decoding`]: enum.ImageError.html#variant.Decoding | ||
| Decoding { format: ImageFormatHint }, |
There was a problem hiding this comment.
Is all of this diff necessary for no_std? Seems a little weird. In particular the comments are no longer accurate. Enum variants are not opaque. It's definitely preferrable to have opaque types to allow changing the field representation / error messages / internal variants.
There was a problem hiding this comment.
Yes I think it is...
Previously error types were custom one using std::error::Error but that can not work in no_std.
The only way to make it work is to use a no_std-compatible lib to handle Error and I only found Snafu.
But I had a feeling it was messy to bundle the error.rs refactor with this PR.
Maybe we can do it in two steps:
- first PR to refactor
error.rsto useSnafu - "main" PR for
no_std
It is a big diff but not a complicated one b/c it is mainly code removal:
- no need to
impl Errorwhen using Snafu - no need to
impl fmt::Displaywhen using Snafu
Question: not sure if what I did is a breaking change?
There was a problem hiding this comment.
These changes to ImageError are a breaking change because the variants of public enums are public. What's not clear to me is whether the changes here are actually necessary. Can Snafu really not derive its trait for enums with tuple variants?
There was a problem hiding this comment.
No it can not (AFAIK) cf shepmaster/snafu#199 and the various comments and linked issues.
Alternatively there is error_in_core rust-lang/rust#103765 but that would make this crate nightly-only.
There was a problem hiding this comment.
What happens if we just gate the impl std::error::Error parts behind std? Would that cause any problems? Because it would be nice to avoid the code churn if possible
There was a problem hiding this comment.
Wouldn't that make all the errors not proper errors in no_std context?
But we can go with your idea and instead[starting by reversing all changes in error.rs]:
- with
std:use std::error::Error, same as before no_std:use core::error::Error
That would makeno_stdbuilds require nightly for now; but that is fine for my use case.
Would that be ok for you?
edit: NOTE: seems to be working fine; using #![cfg_attr(feature = "alloc", feature(error_in_core))] so std build should not be affected by the required nightly
For completeness: there is also the "duplicated code" alternative:
- move original
error.rs->error/error_compat.rs - rename this forks
error.rs->error/error_new.rs - in
error/mod.rsswitch impl based on std vs no_std
|
One comment I want to add outside the workflow of the PR review: If we need to get rid of a core buffer data structure, rewrite the |
- bump `color_quant`: feature `alloc` renamed `num-traits` cf image-rs/color_quant#21 - `ImageDecoder`: remove `Reader` when no_std b/c cleaner
I will try to make it work under But why would it be a dealbreaker?
edit: don't really look at the |
- remove Snafu - require feature `error_in_core` for `no_std` [ci skip]
Both `std` and `no_std` build+test OK - `cargo test --no-default-features --features=default` OK - `cargo +nightly-2022-10-22 test --no-default-features --features=alloc` OK - `cargo +nightly-2022-10-22 no-std-check --no-default-features --features=alloc` OK
TODO TEMP? or keep it that way?
|
See #2462 (comment) but of course this is far older. There's not much to gain from leaving it open, unfortunately. Hopefully other libraries provide the compatibility in |
Hello,
Following up on #1184 (comment) I am opening a PR to discuss
about potential
no_stdsupport.Copy-pasting and rewriting my comment:
TODO?:
no_std]#[cfg(feature = "std")]but I can probably replace most of them by a new e.g.iofeature.imageprocwhich is the one I use directly] → making each and every feature work underno_stdis a different beast I am guessingI'm open to feedback!
I license past and future contributions under the dual MIT/Apache-2.0 license,
allowing licensees to choose either at their option.