Skip to content

Commit

Permalink
Merge branch 'development' of https://github.com/Stremio/stremio-core
Browse files Browse the repository at this point in the history
…into feat/facebook-auth
  • Loading branch information
tymmesyde committed May 10, 2024
2 parents 9d93779 + 4a0b991 commit e5bf4a7
Show file tree
Hide file tree
Showing 29 changed files with 415 additions and 214 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
- name: Rust setup (stable)
uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2

- name: Lint - rustfmt
run: cargo fmt --all -- --check

Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/msrv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
with:
toolchain: ${{ env.RUST_MSRV_VERSION }}

- uses: Swatinem/rust-cache@v2

- name: Checkout
uses: actions/checkout@v4

Expand Down
1 change: 0 additions & 1 deletion src/models/catalog_with_filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use boolinator::Boolinator;
use derivative::Derivative;
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use std::ops::Add;

#[derive(PartialEq, Eq)]
Expand Down
2 changes: 1 addition & 1 deletion src/models/common/resource_loadable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ where
ResourceAction::ResourceRequested { request }
if resource.request != *request || resource.content.is_none() =>
{
resource.request = request.to_owned();
request.clone_into(&mut resource.request);
resource.content = Some(Loadable::Loading);
Effects::future(EffectFuture::Concurrent(
E::addon_transport(&request.base)
Expand Down
10 changes: 5 additions & 5 deletions src/models/ctx/update_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub fn update_profile<E: Env + 'static>(
if addon.flags.protected || profile.addons[addon_position].flags.protected {
return addon_upgrade_error_effects(addon, OtherError::AddonIsProtected);
}
profile.addons[addon_position] = addon.to_owned();
addon.clone_into(&mut profile.addons[addon_position]);
let push_to_api_effects = match profile.auth_key() {
Some(auth_key) => {
Effects::one(push_addons_to_api::<E>(profile.addons.to_owned(), auth_key))
Expand Down Expand Up @@ -223,7 +223,7 @@ pub fn update_profile<E: Env + 'static>(
},
Msg::Action(Action::Ctx(ActionCtx::UpdateSettings(settings))) => {
if profile.settings != *settings {
profile.settings = settings.to_owned();
settings.clone_into(&mut profile.settings);
Effects::msg(Msg::Event(Event::SettingsUpdated {
settings: settings.to_owned(),
}))
Expand Down Expand Up @@ -251,7 +251,7 @@ pub fn update_profile<E: Env + 'static>(
.map(|addon| &addon.transport_url)
.position(|transport_url| *transport_url == addon.transport_url);
if let Some(addon_position) = addon_position {
profile.addons[addon_position] = addon.to_owned();
addon.clone_into(&mut profile.addons[addon_position]);
} else {
profile.addons.push(addon.to_owned());
};
Expand Down Expand Up @@ -324,7 +324,7 @@ pub fn update_profile<E: Env + 'static>(
.chain(removed_transport_urls)
.collect();
let profile_changed_effects = if profile.addons != *addons {
profile.addons = addons.to_owned();
addons.clone_into(&mut profile.addons);

Effects::msg(Msg::Internal(Internal::ProfileChanged))
} else {
Expand Down Expand Up @@ -359,7 +359,7 @@ pub fn update_profile<E: Env + 'static>(
match result {
Ok(user) => match &mut profile.auth {
Some(auth) if auth.user != *user => {
auth.user = user.to_owned();
user.clone_into(&mut auth.user);
Effects::msg(Msg::Event(Event::UserPulledFromAPI { uid: profile.uid() }))
.join(Effects::msg(Msg::Internal(Internal::ProfileChanged)))
}
Expand Down
1 change: 0 additions & 1 deletion src/models/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use derive_more::From;
use enclose::enclose;
use futures::{future, FutureExt, TryFutureExt};
use serde::Serialize;
use std::convert::TryFrom;
use std::fmt;

#[derive(Clone, PartialEq, From, Serialize, Debug)]
Expand Down
2 changes: 0 additions & 2 deletions src/models/local_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,6 @@ mod imdb_rating {

#[cfg(test)]
mod test {
use std::convert::TryFrom;

use super::*;

#[test]
Expand Down
28 changes: 19 additions & 9 deletions src/models/meta_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,16 +288,25 @@ fn selected_guess_stream_update(
}) => meta_path,
_ => return Effects::default(),
};
let meta_item = match meta_items
.iter()
.find_map(|meta_item| match &meta_item.content {
Some(Loadable::Ready(meta_item)) => Some(meta_item),
Some(Loadable::Loading) => None,
_ => None,
}) {
Some(meta_item) => meta_item,
_ => return Effects::default(),

// Wait for all requests to finish before retrieving the meta_item
let meta_item = if meta_items.iter().all(|meta_item| {
matches!(meta_item.content, Some(Loadable::Ready(..)))
|| matches!(meta_item.content, Some(Loadable::Err(..)))
}) {
match meta_items
.iter()
.find_map(|meta_item| match &meta_item.content {
Some(Loadable::Ready(meta_item)) => Some(meta_item),
_ => None,
}) {
Some(meta_item) => meta_item,
_ => return Effects::default(),
}
} else {
return Effects::default();
};

let video_id = match (
meta_item.videos.len(),
&meta_item.preview.behavior_hints.default_video_id,
Expand All @@ -306,6 +315,7 @@ fn selected_guess_stream_update(
(0, None) => meta_item.preview.id.to_owned(),
_ => return Effects::default(),
};

eq_update(
selected,
Some(Selected {
Expand Down
11 changes: 7 additions & 4 deletions src/models/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,8 +430,8 @@ impl<E: Env + 'static> UpdateWithCtx<E> for Player {
.overall_time_watched
.saturating_add(time_watched);
};
library_item.state.time_offset = time.to_owned();
library_item.state.duration = duration.to_owned();
time.clone_into(&mut library_item.state.time_offset);
duration.clone_into(&mut library_item.state.duration);
if library_item.state.flagged_watched == 0
&& library_item.state.time_watched as f64
> library_item.state.duration as f64 * WATCHED_THRESHOLD_COEF
Expand All @@ -452,7 +452,10 @@ impl<E: Env + 'static> UpdateWithCtx<E> for Player {
library_item.temp = true;
};
if let Some(analytics_context) = &mut self.analytics_context {
analytics_context.video_id = library_item.state.video_id.to_owned();
library_item
.state
.video_id
.clone_into(&mut analytics_context.video_id);
analytics_context.time = Some(library_item.state.time_offset);
analytics_context.duration = Some(library_item.state.duration);
analytics_context.device_type = Some(device.to_owned());
Expand Down Expand Up @@ -870,7 +873,7 @@ where

match next_video {
Some(next_video) => {
stream_request.path.id = next_video.id.clone();
stream_request.path.id.clone_from(&next_video.id);

match next_streams.as_mut() {
Some(next_streams) => resource_update_with_vector_content::<E, _>(
Expand Down
73 changes: 48 additions & 25 deletions src/types/addon/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,28 +86,38 @@ pub struct ResourceResponseCache {
#[serde(untagged)]
#[serde_as]
pub enum ResourceResponse {
/// [`MetaItemPreview`] response without the `videos` key of an item
///
/// # Examples
///
/// ```
/// use stremio_core::types::addon::ResourceResponse;
///
/// let null_metas = serde_json::json!({ "metas": null });
/// let null_metas = serde_json::from_value::<ResourceResponse>(null_metas).expect("Should be valid");
///
/// match null_metas {
/// ResourceResponse::Metas { metas } => assert!(metas.is_empty()),
/// _ => panic!("Whoops, wrong variant!"),
/// }
/// ```
Metas {
#[serde_as(as = "VecSkipError<_>")]
metas: Vec<MetaItemPreview>,
},
#[serde(rename_all = "camelCase")]
MetasDetailed {
#[serde_as(as = "VecSkipError<_>")]
metas_detailed: Vec<MetaItem>,
},
Meta {
meta: MetaItem,
},
Streams {
#[serde_as(as = "VecSkipError<_>")]
streams: Vec<Stream>,
},
Subtitles {
#[serde_as(as = "VecSkipError<_>")]
subtitles: Vec<Subtitles>,
},
Addons {
#[serde_as(as = "VecSkipError<_>")]
addons: Vec<DescriptorPreview>,
},
}
Expand Down Expand Up @@ -162,36 +172,49 @@ impl<'de> Deserialize<'de> for ResourceResponse {
}

if let Some(value) = value.get_mut("metas") {
let skip = serde_json::from_value::<SkipError<_>>(value.take())
.map_err(serde::de::Error::custom)?;

Ok(ResourceResponse::Metas { metas: skip.0 })
Ok(ResourceResponse::Metas {
metas: match value.take() {
serde_json::Value::Null => Ok(vec![]),
value => serde_json::from_value::<SkipError<_>>(value).map(|skip| skip.0),
}
.map_err(serde::de::Error::custom)?,
})
} else if let Some(value) = value.get_mut("metasDetailed") {
let skip = serde_json::from_value::<SkipError<_>>(value.take())
.map_err(serde::de::Error::custom)?;

Ok(ResourceResponse::MetasDetailed {
metas_detailed: skip.0,
metas_detailed: match value.take() {
serde_json::Value::Null => Ok(vec![]),
value => serde_json::from_value::<SkipError<_>>(value).map(|skip| skip.0),
}
.map_err(serde::de::Error::custom)?,
})
} else if let Some(value) = value.get_mut("meta") {
Ok(ResourceResponse::Meta {
meta: serde_json::from_value(value.take()).map_err(serde::de::Error::custom)?,
})
} else if let Some(value) = value.get_mut("streams") {
let skip = serde_json::from_value::<SkipError<_>>(value.take())
.map_err(serde::de::Error::custom)?;

Ok(ResourceResponse::Streams { streams: skip.0 })
Ok(ResourceResponse::Streams {
streams: match value.take() {
serde_json::Value::Null => Ok(vec![]),
value => serde_json::from_value::<SkipError<_>>(value).map(|skip| skip.0),
}
.map_err(serde::de::Error::custom)?,
})
} else if let Some(value) = value.get_mut("subtitles") {
let skip = serde_json::from_value::<SkipError<_>>(value.take())
.map_err(serde::de::Error::custom)?;

Ok(ResourceResponse::Subtitles { subtitles: skip.0 })
Ok(ResourceResponse::Subtitles {
subtitles: match value.take() {
serde_json::Value::Null => Ok(vec![]),
value => serde_json::from_value::<SkipError<_>>(value).map(|skip| skip.0),
}
.map_err(serde::de::Error::custom)?,
})
} else if let Some(value) = value.get_mut("addons") {
let skip = serde_json::from_value::<SkipError<_>>(value.take())
.map_err(serde::de::Error::custom)?;

Ok(ResourceResponse::Addons { addons: skip.0 })
Ok(ResourceResponse::Addons {
addons: match value.take() {
serde_json::Value::Null => Ok(vec![]),
value => serde_json::from_value::<SkipError<_>>(value).map(|skip| skip.0),
}
.map_err(serde::de::Error::custom)?,
})
} else {
// we should never get to this else, as we already check for missing required key
// but we're leaving it to remove the danger of a developer forgetting to add a new key to the list.
Expand Down
Loading

0 comments on commit e5bf4a7

Please sign in to comment.