Skip to content

Commit

Permalink
Explain the purpose of the ImageSource::Bytes URI (#3402)
Browse files Browse the repository at this point in the history
Closes #3363
  • Loading branch information
emilk authored Sep 27, 2023
1 parent a9272e0 commit dbf3405
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 22 deletions.
8 changes: 4 additions & 4 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,10 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) {
#[macro_export]
macro_rules! include_image {
($path: literal) => {
$crate::ImageSource::Bytes(
::std::borrow::Cow::Borrowed(concat!("bytes://", $path)), // uri
$crate::load::Bytes::Static(include_bytes!($path)),
)
$crate::ImageSource::Bytes {
uri: ::std::borrow::Cow::Borrowed(concat!("bytes://", $path)),
bytes: $crate::load::Bytes::Static(include_bytes!($path)),
}
};
}

Expand Down
8 changes: 4 additions & 4 deletions crates/egui/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ pub enum LoadError {
/// Programmer error: There are no image loaders installed.
NoImageLoaders,

/// A specific loader does not support this schema, protocol or image format.
/// A specific loader does not support this scheme, protocol or image format.
NotSupported,

/// Programmer error: Failed to find the bytes for this image because
/// there was no [`BytesLoader`] supporting the schema.
/// there was no [`BytesLoader`] supporting the scheme.
NoMatchingBytesLoader,

/// Programmer error: Failed to parse the bytes as an image because
/// there was no [`ImageLoader`] supporting the schema.
/// there was no [`ImageLoader`] supporting the scheme.
NoMatchingImageLoader,

/// Programmer error: no matching [`TextureLoader`].
Expand All @@ -111,7 +111,7 @@ impl Display for LoadError {

Self::NoMatchingTextureLoader => f.write_str("No matching TextureLoader. Did you remove the default one?"),

Self::NotSupported => f.write_str("Iagge schema or URI not supported by this loader"),
Self::NotSupported => f.write_str("Image scheme or URI not supported by this loader"),

Self::Loading(message) => f.write_str(message),
}
Expand Down
48 changes: 34 additions & 14 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ impl<'a> Image<'a> {
///
/// See [`ImageSource::Bytes`].
pub fn from_bytes(uri: impl Into<Cow<'static, str>>, bytes: impl Into<Bytes>) -> Self {
Self::new(ImageSource::Bytes(uri.into(), bytes.into()))
Self::new(ImageSource::Bytes {
uri: uri.into(),
bytes: bytes.into(),
})
}

/// Texture options used when creating the texture.
Expand Down Expand Up @@ -275,7 +278,7 @@ impl<'a> Image<'a> {
pub fn size(&self) -> Option<Vec2> {
match &self.source {
ImageSource::Texture(texture) => Some(texture.size),
ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None,
ImageSource::Uri(_) | ImageSource::Bytes { .. } => None,
}
}

Expand Down Expand Up @@ -478,9 +481,10 @@ impl Default for ImageSize {
/// This is used by [`Image::new`] and [`Ui::image`].
#[derive(Clone)]
pub enum ImageSource<'a> {
/// Load the image from a URI.
/// Load the image from a URI, e.g. `https://example.com/image.png`.
///
/// This could be a `file://` path, `https://` url, `bytes://` identifier, or some other scheme.
///
/// This could be a `file://` url, `http(s)?://` url, or a `bare` identifier.
/// How the URI will be turned into a texture for rendering purposes is
/// up to the registered loaders to handle.
///
Expand All @@ -495,8 +499,6 @@ pub enum ImageSource<'a> {

/// Load the image from some raw bytes.
///
/// For better error messages, use the `bytes://` prefix for the URI.
///
/// The [`Bytes`] may be:
/// - `'static`, obtained from `include_bytes!` or similar
/// - Anything that can be converted to `Arc<[u8]>`
Expand All @@ -506,13 +508,22 @@ pub enum ImageSource<'a> {
/// See also [`include_image`] for an easy way to load and display static images.
///
/// See [`crate::load`] for more information.
Bytes(Cow<'static, str>, Bytes),
Bytes {
/// The unique identifier for this image, e.g. `bytes://my_logo.png`.
///
/// You should use a proper extension (`.jpg`, `.png`, `.svg`, etc) for the image to load properly.
///
/// Use the `bytes://` scheme for the URI for better error messages.
uri: Cow<'static, str>,

bytes: Bytes,
},
}

impl<'a> std::fmt::Debug for ImageSource<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => uri.as_ref().fmt(f),
ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => uri.as_ref().fmt(f),
ImageSource::Texture(st) => st.id.fmt(f),
}
}
Expand All @@ -524,7 +535,7 @@ impl<'a> ImageSource<'a> {
pub fn texture_size(&self) -> Option<Vec2> {
match self {
ImageSource::Texture(texture) => Some(texture.size),
ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None,
ImageSource::Uri(_) | ImageSource::Bytes { .. } => None,
}
}

Expand All @@ -539,7 +550,7 @@ impl<'a> ImageSource<'a> {
match self {
Self::Texture(texture) => Ok(TexturePoll::Ready { texture }),
Self::Uri(uri) => ctx.try_load_texture(uri.as_ref(), texture_options, size_hint),
Self::Bytes(uri, bytes) => {
Self::Bytes { uri, bytes } => {
ctx.include_bytes(uri.clone(), bytes);
ctx.try_load_texture(uri.as_ref(), texture_options, size_hint)
}
Expand All @@ -551,7 +562,7 @@ impl<'a> ImageSource<'a> {
/// This will return `None` for [`Self::Texture`].
pub fn uri(&self) -> Option<&str> {
match self {
ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => Some(uri),
ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => Some(uri),
ImageSource::Texture(_) => None,
}
}
Expand Down Expand Up @@ -644,21 +655,30 @@ impl<'a> From<Cow<'a, str>> for ImageSource<'a> {
impl<T: Into<Bytes>> From<(&'static str, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (&'static str, T)) -> Self {
Self::Bytes(uri.into(), bytes.into())
Self::Bytes {
uri: uri.into(),
bytes: bytes.into(),
}
}
}

impl<T: Into<Bytes>> From<(Cow<'static, str>, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (Cow<'static, str>, T)) -> Self {
Self::Bytes(uri, bytes.into())
Self::Bytes {
uri,
bytes: bytes.into(),
}
}
}

impl<T: Into<Bytes>> From<(String, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (String, T)) -> Self {
Self::Bytes(uri.into(), bytes.into())
Self::Bytes {
uri: uri.into(),
bytes: bytes.into(),
}
}
}

Expand Down

0 comments on commit dbf3405

Please sign in to comment.