diff options
author | 2024-02-28 15:18:49 -0800 | |
---|---|---|
committer | 2024-04-27 13:25:55 -0700 | |
commit | af0be6ec97cffc2bdd1dad33f1cbdfc8947baba7 (patch) | |
tree | 41cd47470de3628eac31001e3647b0905f45f1e0 | |
parent | a1afe6a43863652f1324cbadd6e30f988b7bd683 (diff) | |
download | trakt-by-ref.tar.gz trakt-by-ref.tar.zst trakt-by-ref.zip |
perf: reduces allocations in scrobble endpointby-ref
-rw-r--r-- | trakt-rs/src/api/scrobble.rs | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/trakt-rs/src/api/scrobble.rs b/trakt-rs/src/api/scrobble.rs index c064890..0cb45e0 100644 --- a/trakt-rs/src/api/scrobble.rs +++ b/trakt-rs/src/api/scrobble.rs @@ -4,21 +4,41 @@ use serde::Deserialize; -use crate::smo::{Episode, Movie, Sharing, Show}; +use crate::smo::{Episode, Ids, Movie, Sharing, Show}; + +#[derive(Debug, serde::Serialize)] +#[serde(rename_all = "lowercase")] +enum BodyInner { + Movie { ids: Ids }, + Episode { ids: Ids }, +} + +#[derive(Debug, serde::Serialize)] +struct Body { + #[serde(flatten)] + inner: BodyInner, + progress: f64, +} mod _private { use crate::smo::{Episode, Movie}; + #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] + pub enum CheckinItemType { + Movie, + Episode, + } + pub trait Sealed { - const KEY: &'static str; + const KEY: CheckinItemType; } impl Sealed for Movie { - const KEY: &'static str = "movie"; + const KEY: CheckinItemType = CheckinItemType::Movie; } impl Sealed for Episode { - const KEY: &'static str = "episode"; + const KEY: CheckinItemType = CheckinItemType::Episode; } } @@ -69,10 +89,9 @@ pub mod start { //! <https://trakt.docs.apiary.io/#reference/scrobble/start/start-watching-in-a-media-center> use bytes::BufMut; - use serde_json::{json, Value}; use trakt_core::{error::IntoHttpError, Context, Metadata}; - use super::ScrobbleItem; + use super::{Body, BodyInner, ScrobbleItem, _private::CheckinItemType}; use crate::smo::{Episode, Id, Ids, Movie}; #[derive(Debug, Clone, PartialEq)] @@ -125,12 +144,17 @@ pub mod start { let body = T::default(); let mut writer = body.writer(); - let json = Value::Object({ - let mut map = serde_json::Map::new(); - map.insert(I::KEY.to_owned(), json!({ "ids": Ids::from(self.id) })); - map.insert("progress".to_owned(), json!(self.progress)); - map - }); + let json = Body { + inner: match I::KEY { + CheckinItemType::Movie => BodyInner::Movie { + ids: Ids::from(self.id), + }, + CheckinItemType::Episode => BodyInner::Episode { + ids: Ids::from(self.id), + }, + }, + progress: self.progress, + }; serde_json::to_writer(&mut writer, &json)?; @@ -145,9 +169,9 @@ pub mod pause { //! <https://trakt.docs.apiary.io/#reference/scrobble/pause/pause-watching-in-a-media-center> use bytes::BufMut; - use serde_json::{json, Value}; use trakt_core::{error::IntoHttpError, Context, Metadata}; + use super::{Body, BodyInner, _private::CheckinItemType}; use crate::{ api::scrobble::ScrobbleItem, smo::{Episode, Id, Ids, Movie}, @@ -203,13 +227,17 @@ pub mod pause { let body = T::default(); let mut writer = body.writer(); - let json = Value::Object({ - let mut map = serde_json::Map::new(); - map.insert(I::KEY.to_owned(), json!({ "ids": Ids::from(self.id) })); - map.insert("progress".to_owned(), json!(self.progress)); - map - }); - + let json = Body { + inner: match I::KEY { + CheckinItemType::Movie => BodyInner::Movie { + ids: Ids::from(self.id), + }, + CheckinItemType::Episode => BodyInner::Episode { + ids: Ids::from(self.id), + }, + }, + progress: self.progress, + }; serde_json::to_writer(&mut writer, &json)?; trakt_core::construct_req(&ctx, &Self::METADATA, &(), &(), writer.into_inner()) @@ -223,9 +251,9 @@ pub mod stop { //! <https://trakt.docs.apiary.io/#reference/scrobble/stop/stop-or-finish-watching-in-a-media-center> use bytes::BufMut; - use serde_json::{json, Value}; use trakt_core::{error::IntoHttpError, Context, Metadata}; + use super::{Body, BodyInner, _private::CheckinItemType}; use crate::{ api::scrobble::ScrobbleItem, smo::{Episode, Id, Ids, Movie}, @@ -281,13 +309,17 @@ pub mod stop { let body = T::default(); let mut writer = body.writer(); - let json = Value::Object({ - let mut map = serde_json::Map::new(); - map.insert(I::KEY.to_owned(), json!({ "ids": Ids::from(self.id) })); - map.insert("progress".to_owned(), json!(self.progress)); - map - }); - + let json = Body { + inner: match I::KEY { + CheckinItemType::Movie => BodyInner::Movie { + ids: Ids::from(self.id), + }, + CheckinItemType::Episode => BodyInner::Episode { + ids: Ids::from(self.id), + }, + }, + progress: self.progress, + }; serde_json::to_writer(&mut writer, &json)?; trakt_core::construct_req(&ctx, &Self::METADATA, &(), &(), writer.into_inner()) |