mirror of
https://github.com/teloxide/teloxide.git
synced 2024-12-22 14:35:36 +01:00
Add dedicated Rgb
struct to replace [u8; 3]
This commit is contained in:
parent
7b2de9ad39
commit
181b30304f
13 changed files with 164 additions and 88 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -235,6 +235,12 @@ version = "3.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
|
@ -1668,6 +1674,15 @@ dependencies = [
|
||||||
"windows-registry",
|
"windows-registry",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rgb"
|
||||||
|
version = "0.8.48"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f86ae463694029097b846d8f99fd5536740602ae00022c0c50c5600720b2f71"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.8"
|
version = "0.17.8"
|
||||||
|
@ -2302,6 +2317,7 @@ dependencies = [
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rc-box",
|
"rc-box",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
"rgb",
|
||||||
"ron",
|
"ron",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -2791,7 +2807,7 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -49,6 +49,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- MSRV (Minimal Supported Rust Version) was bumped from `1.70.0` to `1.80.0`
|
- MSRV (Minimal Supported Rust Version) was bumped from `1.70.0` to `1.80.0`
|
||||||
- Some dependencies was bumped: `reqwest` to `0.12.7` and `ron` to `0.8.1`
|
- Some dependencies was bumped: `reqwest` to `0.12.7` and `ron` to `0.8.1`
|
||||||
- `tokio` version was explicitly specified as `1.39` and feature `io-util` was enabled for it
|
- `tokio` version was explicitly specified as `1.39` and feature `io-util` was enabled for it
|
||||||
|
- `[u8; 3]` sometimes used for RGB values was replaced with dedicated `Rgb` struct: ([#1151][pr1151])
|
||||||
|
- `serde_rgb` module from `types.rs` file was removed
|
||||||
|
- `CreateForumTopic`, `ForumTopicCreated` and `ForumTopic` structs now use `Rgb` instead of `[u8; 3]` for `icon_color` field
|
||||||
|
- Added `rgb` crate dependency to Cargo.toml
|
||||||
|
- Added `Rgb` struct with `From` implementation for `RGB8` type from popular `rgb` crate
|
||||||
|
|
||||||
- Support for TBA 7.2 ([#1146](pr1146))
|
- Support for TBA 7.2 ([#1146](pr1146))
|
||||||
- Remove `flags` field from `StickerSet` struct
|
- Remove `flags` field from `StickerSet` struct
|
||||||
|
@ -60,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
[pr1134]: https://github.com/teloxide/teloxide/pull/1134
|
[pr1134]: https://github.com/teloxide/teloxide/pull/1134
|
||||||
[pr1146]: https://github.com/teloxide/teloxide/pull/1146
|
[pr1146]: https://github.com/teloxide/teloxide/pull/1146
|
||||||
[pr1147]: https://github.com/teloxide/teloxide/pull/1147
|
[pr1147]: https://github.com/teloxide/teloxide/pull/1147
|
||||||
|
[pr1151]: https://github.com/teloxide/teloxide/pull/1151
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ rc-box = "1.1.1"
|
||||||
chrono = { version = "0.4.32", default-features = false }
|
chrono = { version = "0.4.32", default-features = false }
|
||||||
either = "1.6.1"
|
either = "1.6.1"
|
||||||
bitflags = { version = "1.2" }
|
bitflags = { version = "1.2" }
|
||||||
|
rgb = "0.8.48"
|
||||||
|
|
||||||
vecrem = { version = "0.1", optional = true }
|
vecrem = { version = "0.1", optional = true }
|
||||||
|
|
||||||
|
|
|
@ -2754,9 +2754,11 @@ Schema(
|
||||||
),
|
),
|
||||||
Param(
|
Param(
|
||||||
name: "icon_color",
|
name: "icon_color",
|
||||||
// FIXME: use an Rgb or something
|
ty: RawTy("Rgb"),
|
||||||
ty: u32,
|
descr: Doc(
|
||||||
descr: Doc(md: "Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)")
|
md: "Color of the topic icon in RGB format. Currently, must be one of 7322096 (`0x6FB9F0`), 16766590 (`0xFFD67E`), 13338331 (`0xCB86DB`), 9367192 (`0x8EEE98`), 16749490 (`0xFF93B2`), or 16478047 (`0xFB6F5F`). To construct color from these values use [`Rgb::from_u32`]",
|
||||||
|
md_links: {"`Rgb::from_u32`": "crate::types::Rgb::from_u32"}
|
||||||
|
)
|
||||||
),
|
),
|
||||||
Param(
|
Param(
|
||||||
name: "icon_custom_emoji_id",
|
name: "icon_custom_emoji_id",
|
||||||
|
|
|
@ -671,7 +671,7 @@ trait ErasableRequester<'a> {
|
||||||
&self,
|
&self,
|
||||||
chat_id: Recipient,
|
chat_id: Recipient,
|
||||||
name: String,
|
name: String,
|
||||||
icon_color: u32,
|
icon_color: Rgb,
|
||||||
icon_custom_emoji_id: String,
|
icon_custom_emoji_id: String,
|
||||||
) -> ErasedRequest<'a, CreateForumTopic, Self::Err>;
|
) -> ErasedRequest<'a, CreateForumTopic, Self::Err>;
|
||||||
|
|
||||||
|
@ -1506,7 +1506,7 @@ where
|
||||||
&self,
|
&self,
|
||||||
chat_id: Recipient,
|
chat_id: Recipient,
|
||||||
name: String,
|
name: String,
|
||||||
icon_color: u32,
|
icon_color: Rgb,
|
||||||
icon_custom_emoji_id: String,
|
icon_custom_emoji_id: String,
|
||||||
) -> ErasedRequest<'a, CreateForumTopic, Self::Err> {
|
) -> ErasedRequest<'a, CreateForumTopic, Self::Err> {
|
||||||
Requester::create_forum_topic(self, chat_id, name, icon_color, icon_custom_emoji_id).erase()
|
Requester::create_forum_topic(self, chat_id, name, icon_color, icon_custom_emoji_id).erase()
|
||||||
|
|
|
@ -6,7 +6,7 @@ use crate::{
|
||||||
requests::{JsonRequest, MultipartRequest},
|
requests::{JsonRequest, MultipartRequest},
|
||||||
types::{
|
types::{
|
||||||
BotCommand, BusinessConnectionId, ChatId, ChatPermissions, InlineQueryResult, InputFile,
|
BotCommand, BusinessConnectionId, ChatId, ChatPermissions, InlineQueryResult, InputFile,
|
||||||
InputMedia, InputSticker, LabeledPrice, MessageId, Recipient, StickerFormat, ThreadId,
|
InputMedia, InputSticker, LabeledPrice, MessageId, Recipient, Rgb, StickerFormat, ThreadId,
|
||||||
UserId,
|
UserId,
|
||||||
},
|
},
|
||||||
Bot,
|
Bot,
|
||||||
|
@ -686,7 +686,7 @@ impl Requester for Bot {
|
||||||
&self,
|
&self,
|
||||||
chat_id: C,
|
chat_id: C,
|
||||||
name: N,
|
name: N,
|
||||||
icon_color: u32,
|
icon_color: Rgb,
|
||||||
icon_custom_emoji_id: I,
|
icon_custom_emoji_id: I,
|
||||||
) -> Self::CreateForumTopic
|
) -> Self::CreateForumTopic
|
||||||
where
|
where
|
||||||
|
|
|
@ -949,11 +949,11 @@ macro_rules! requester_forward {
|
||||||
(@method create_forum_topic $body:ident $ty:ident) => {
|
(@method create_forum_topic $body:ident $ty:ident) => {
|
||||||
type CreateForumTopic = $ty![CreateForumTopic];
|
type CreateForumTopic = $ty![CreateForumTopic];
|
||||||
|
|
||||||
fn create_forum_topic<C, N, I>(&self, chat_id: C, name: N, icon_color: u32, icon_custom_emoji_id: I) -> Self::CreateForumTopic where C: Into<Recipient>,
|
fn create_forum_topic<C, N, I>(&self, chat_id: C, name: N, icon_color: Rgb, icon_custom_emoji_id: I) -> Self::CreateForumTopic where C: Into<Recipient>,
|
||||||
N: Into<String>,
|
N: Into<String>,
|
||||||
I: Into<String> {
|
I: Into<String> {
|
||||||
let this = self;
|
let this = self;
|
||||||
$body!(create_forum_topic this (chat_id: C, name: N, icon_color: u32, icon_custom_emoji_id: I))
|
$body!(create_forum_topic this (chat_id: C, name: N, icon_color: Rgb, icon_custom_emoji_id: I))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(@method edit_forum_topic $body:ident $ty:ident) => {
|
(@method edit_forum_topic $body:ident $ty:ident) => {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::types::{ForumTopic, Recipient};
|
use crate::types::{ForumTopic, Recipient, Rgb};
|
||||||
|
|
||||||
impl_payload! {
|
impl_payload! {
|
||||||
/// Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. Returns information about the created topic as a `ForumTopic` object.
|
/// Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the _can\_manage\_topics_ administrator rights. Returns information about the created topic as a `ForumTopic` object.
|
||||||
|
@ -13,8 +13,10 @@ impl_payload! {
|
||||||
pub chat_id: Recipient [into],
|
pub chat_id: Recipient [into],
|
||||||
/// Topic name, 1-128 characters
|
/// Topic name, 1-128 characters
|
||||||
pub name: String [into],
|
pub name: String [into],
|
||||||
/// Color of the topic icon in RGB format. Currently, must be one of 7322096 (0x6FB9F0), 16766590 (0xFFD67E), 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F)
|
/// Color of the topic icon in RGB format. Currently, must be one of 7322096 (`0x6FB9F0`), 16766590 (`0xFFD67E`), 13338331 (`0xCB86DB`), 9367192 (`0x8EEE98`), 16749490 (`0xFF93B2`), or 16478047 (`0xFB6F5F`). To construct color from these values use [`Rgb::from_u32`]
|
||||||
pub icon_color: u32,
|
///
|
||||||
|
/// [`Rgb::from_u32`]: crate::types::Rgb::from_u32
|
||||||
|
pub icon_color: Rgb,
|
||||||
/// Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers.
|
/// Unique identifier of the custom emoji shown as the topic icon. Use `getForumTopicIconStickers` to get all allowed custom emoji identifiers.
|
||||||
pub icon_custom_emoji_id: String [into],
|
pub icon_custom_emoji_id: String [into],
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,7 +702,7 @@ pub trait Requester {
|
||||||
&self,
|
&self,
|
||||||
chat_id: C,
|
chat_id: C,
|
||||||
name: N,
|
name: N,
|
||||||
icon_color: u32,
|
icon_color: Rgb,
|
||||||
icon_custom_emoji_id: I,
|
icon_custom_emoji_id: I,
|
||||||
) -> Self::CreateForumTopic
|
) -> Self::CreateForumTopic
|
||||||
where
|
where
|
||||||
|
|
|
@ -128,6 +128,7 @@ pub use reply_markup::*;
|
||||||
pub use reply_parameters::*;
|
pub use reply_parameters::*;
|
||||||
pub use request_id::*;
|
pub use request_id::*;
|
||||||
pub use response_parameters::*;
|
pub use response_parameters::*;
|
||||||
|
pub use rgb::*;
|
||||||
pub use sent_web_app_message::*;
|
pub use sent_web_app_message::*;
|
||||||
pub use shared_user::*;
|
pub use shared_user::*;
|
||||||
pub use shipping_address::*;
|
pub use shipping_address::*;
|
||||||
|
@ -262,6 +263,7 @@ mod reply_markup;
|
||||||
mod reply_parameters;
|
mod reply_parameters;
|
||||||
mod request_id;
|
mod request_id;
|
||||||
mod response_parameters;
|
mod response_parameters;
|
||||||
|
mod rgb;
|
||||||
mod sent_web_app_message;
|
mod sent_web_app_message;
|
||||||
mod shared_user;
|
mod shared_user;
|
||||||
mod shipping_address;
|
mod shipping_address;
|
||||||
|
@ -544,67 +546,3 @@ pub(crate) mod option_msg_id_as_int {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) mod serde_rgb {
|
|
||||||
use serde::{de::Visitor, Deserializer, Serializer};
|
|
||||||
|
|
||||||
pub fn serialize<S: Serializer>(&this: &[u8; 3], s: S) -> Result<S::Ok, S::Error> {
|
|
||||||
s.serialize_u32(to_u32(this))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<[u8; 3], D::Error> {
|
|
||||||
struct V;
|
|
||||||
|
|
||||||
impl Visitor<'_> for V {
|
|
||||||
type Value = [u8; 3];
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
formatter.write_str("an integer represeting an RGB color")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
Ok(from_u32(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
self.visit_u32(v.try_into().map_err(|_| E::custom("rgb value doesn't fit u32"))?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
d.deserialize_u32(V)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_u32([r, g, b]: [u8; 3]) -> u32 {
|
|
||||||
u32::from_be_bytes([0, r, g, b])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_u32(rgb: u32) -> [u8; 3] {
|
|
||||||
let [_, r, g, b] = rgb.to_be_bytes();
|
|
||||||
[r, g, b]
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn bytes() {
|
|
||||||
assert_eq!(to_u32([0xAA, 0xBB, 0xCC]), 0x00AABBCC);
|
|
||||||
assert_eq!(from_u32(0x00AABBCC), [0xAA, 0xBB, 0xCC]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn json() {
|
|
||||||
#[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
|
||||||
struct Struct {
|
|
||||||
#[serde(with = "self")]
|
|
||||||
color: [u8; 3],
|
|
||||||
}
|
|
||||||
|
|
||||||
let json = format!(r#"{{"color":{}}}"#, 0x00AABBCC);
|
|
||||||
let Struct { color } = serde_json::from_str(&json).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(color, [0xAA, 0xBB, 0xCC])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::types::ThreadId;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::{Rgb, ThreadId};
|
||||||
|
|
||||||
/// This object represents a forum topic.
|
/// This object represents a forum topic.
|
||||||
///
|
///
|
||||||
/// [The official docs](https://core.telegram.org/bots/api#forumtopiccreated).
|
/// [The official docs](https://core.telegram.org/bots/api#forumtopiccreated).
|
||||||
|
@ -16,9 +16,7 @@ pub struct ForumTopic {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// Color of the topic icon in RGB format.
|
/// Color of the topic icon in RGB format.
|
||||||
// FIXME: use/add a specialized rgb color type?
|
pub icon_color: Rgb,
|
||||||
#[serde(with = "crate::types::serde_rgb")]
|
|
||||||
pub icon_color: [u8; 3],
|
|
||||||
|
|
||||||
/// Unique identifier of the custom emoji shown as the topic icon.
|
/// Unique identifier of the custom emoji shown as the topic icon.
|
||||||
// FIXME: CustomEmojiId
|
// FIXME: CustomEmojiId
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::types::Rgb;
|
||||||
|
|
||||||
/// This object represents a service message about a new forum topic created in
|
/// This object represents a service message about a new forum topic created in
|
||||||
/// the chat.
|
/// the chat.
|
||||||
///
|
///
|
||||||
|
@ -11,9 +13,7 @@ pub struct ForumTopicCreated {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
||||||
/// Color of the topic icon in RGB format.
|
/// Color of the topic icon in RGB format.
|
||||||
// FIXME: use/add a specialized rgb color type?
|
pub icon_color: Rgb,
|
||||||
#[serde(with = "crate::types::serde_rgb")]
|
|
||||||
pub icon_color: [u8; 3],
|
|
||||||
|
|
||||||
/// Unique identifier of the custom emoji shown as the topic icon.
|
/// Unique identifier of the custom emoji shown as the topic icon.
|
||||||
// FIXME: CustomEmojiId
|
// FIXME: CustomEmojiId
|
||||||
|
@ -22,7 +22,7 @@ pub struct ForumTopicCreated {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::types::ForumTopicCreated;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deserialization() {
|
fn deserialization() {
|
||||||
|
@ -32,7 +32,7 @@ mod tests {
|
||||||
let event = serde_json::from_str::<ForumTopicCreated>(json).unwrap();
|
let event = serde_json::from_str::<ForumTopicCreated>(json).unwrap();
|
||||||
|
|
||||||
assert_eq!(event.name, "???");
|
assert_eq!(event.name, "???");
|
||||||
assert_eq!(event.icon_color, [0x8E, 0xEE, 0x98]);
|
assert_eq!(event.icon_color, Rgb { r: 0x8E, g: 0xEE, b: 0x98 });
|
||||||
assert_eq!(event.icon_custom_emoji_id.as_deref(), Some("5312536423851630001"));
|
assert_eq!(event.icon_custom_emoji_id.as_deref(), Some("5312536423851630001"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
113
crates/teloxide-core/src/types/rgb.rs
Normal file
113
crates/teloxide-core/src/types/rgb.rs
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
use rgb::RGB8;
|
||||||
|
use serde::{de::Visitor, Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// RGB color format
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct Rgb {
|
||||||
|
pub r: u8,
|
||||||
|
pub g: u8,
|
||||||
|
pub b: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rgb {
|
||||||
|
/// Convert a [`Rgb`] struct into a big endian `u32` representing the RGB
|
||||||
|
/// color.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use teloxide_core::types::Rgb;
|
||||||
|
/// assert_eq!(Rgb { r: 0xAA, g: 0xBB, b: 0xCC }.to_u32(), 0xAABBCC);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Rgb`]: Rgb
|
||||||
|
pub fn to_u32(self) -> u32 {
|
||||||
|
u32::from_be_bytes([0, self.r, self.g, self.b])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a big endian `u32` representing the RGB color into a [`Rgb`]
|
||||||
|
/// struct.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use teloxide_core::types::Rgb;
|
||||||
|
/// assert_eq!(Rgb::from_u32(0xAABBCC), Rgb { r: 0xAA, g: 0xBB, b: 0xCC });
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Rgb`]: Rgb
|
||||||
|
pub fn from_u32(rgb: u32) -> Self {
|
||||||
|
let [_, r, g, b] = rgb.to_be_bytes();
|
||||||
|
Rgb { r, g, b }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for Rgb {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_u32(self.to_u32())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'de> Deserialize<'de> for Rgb {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct V;
|
||||||
|
|
||||||
|
impl Visitor<'_> for V {
|
||||||
|
type Value = Rgb;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
formatter.write_str("an integer represeting an RGB color")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
Ok(Self::Value::from_u32(v))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: serde::de::Error,
|
||||||
|
{
|
||||||
|
self.visit_u32(v.try_into().map_err(|_| E::custom("rgb value doesn't fit u32"))?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_u32(V)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<RGB8> for Rgb {
|
||||||
|
fn from(color: RGB8) -> Self {
|
||||||
|
Rgb { r: color.r, g: color.g, b: color.b }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn json() {
|
||||||
|
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
struct Struct {
|
||||||
|
color: Rgb,
|
||||||
|
}
|
||||||
|
|
||||||
|
let json = format!(r#"{{"color":{}}}"#, 0x00AABBCC);
|
||||||
|
let Struct { color } = serde_json::from_str(&json).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(color, Rgb { r: 0xAA, g: 0xBB, b: 0xCC })
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue