feat(client): changed all resources so that the URLs include the server's base URL

BREAKING CHANGE:
This commit is contained in:
Scott Lyons 2024-08-12 01:01:20 -07:00
commit ab2ca394ed
3 changed files with 251 additions and 48 deletions

View file

@ -28,6 +28,14 @@ pub struct UnpagedSearchResult<T> {
pub results: Vec<T>,
}
impl<T: WithBaseURL> WithBaseURL for UnpagedSearchResult<T> {
fn with_base_url(self, url: &str) -> Self {
Self {
results: self.results.with_base_url(url),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
/// A result of search operation that involves paging
///
@ -46,6 +54,33 @@ pub struct PagedSearchResult<T> {
pub results: Vec<T>,
}
impl<T: WithBaseURL> WithBaseURL for PagedSearchResult<T> {
fn with_base_url(self, url: &str) -> Self {
Self {
results: self.results.with_base_url(url),
..self
}
}
}
pub(crate) trait WithBaseURL {
fn with_base_url(self, url: &str) -> Self;
}
impl<T: WithBaseURL> WithBaseURL for Option<T> {
fn with_base_url(self, url: &str) -> Self {
self.map(|inner| inner.with_base_url(url))
}
}
impl<T: WithBaseURL> WithBaseURL for Vec<T> {
fn with_base_url(self, url: &str) -> Self {
self.into_iter()
.map(|inner| inner.with_base_url(url))
.collect()
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
/// A [tag resource](TagResource) stripped down to `names`, `category` and `usages` fields.
pub struct MicroTagResource {
@ -265,6 +300,19 @@ pub struct MicroPostResource {
pub thumbnail_url: String,
}
impl WithBaseURL for MicroPostResource {
fn with_base_url(self, url: &str) -> Self {
if !self.thumbnail_url.contains(url) {
MicroPostResource {
id: self.id,
thumbnail_url: format!("{}{}", url, self.thumbnail_url),
}
} else {
self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[doc(hidden)]
pub(crate) struct PostId {
@ -346,6 +394,40 @@ pub struct PostResource {
pub pools: Option<Vec<PoolResource>>,
}
impl WithBaseURL for PostResource {
fn with_base_url(self, url: &str) -> Self {
let curl = self.content_url.map(|cu| {
if !cu.contains(url) {
format!("{}{}", url, cu)
} else {
cu
}
});
let turl = self.thumbnail_url.map(|tu| {
if !tu.contains(url) {
format!("{}{}", url, tu)
} else {
tu
}
});
let user = self.user.with_base_url(url);
let relations = self.relations.with_base_url(url);
let fv_by = self.favorited_by.with_base_url(url);
let pools = self.pools.with_base_url(url);
PostResource {
content_url: curl,
thumbnail_url: turl,
user,
relations,
favorited_by: fv_by,
pools,
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder)]
#[builder(setter(strip_option))]
#[serde(rename_all = "camelCase")]
@ -509,6 +591,22 @@ pub struct UserResource {
pub favorite_post_count: Option<SzuruEither<u32, bool>>,
}
impl WithBaseURL for UserResource {
fn with_base_url(self, url: &str) -> Self {
let av_url = self.avatar_url.map(|au| {
if !au.contains(url) {
format!("{}{}", url, au)
} else {
au
}
});
UserResource {
avatar_url: av_url,
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, Builder)]
#[builder(setter(strip_option))]
#[serde(rename_all = "camelCase")]
@ -548,6 +646,19 @@ pub struct MicroUserResource {
pub avatar_url: String,
}
impl WithBaseURL for MicroUserResource {
fn with_base_url(self, url: &str) -> Self {
if !self.avatar_url.contains(url) {
MicroUserResource {
name: self.name,
avatar_url: format!("{}{}", url, self.avatar_url),
}
} else {
self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// A single user token
@ -572,6 +683,15 @@ pub struct UserAuthTokenResource {
pub last_usage_time: Option<DateTime<Utc>>,
}
impl WithBaseURL for UserAuthTokenResource {
fn with_base_url(self, url: &str) -> Self {
Self {
user: self.user.with_base_url(url),
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Default)]
#[builder(setter(into, strip_option))]
#[serde(rename_all = "kebab-case")]
@ -727,6 +847,15 @@ pub struct PoolResource {
pub description: Option<String>,
}
impl WithBaseURL for PoolResource {
fn with_base_url(self, url: &str) -> Self {
PoolResource {
posts: self.posts.with_base_url(url),
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Builder, Default)]
#[builder(setter(strip_option))]
#[serde(rename_all = "camelCase")]
@ -912,6 +1041,20 @@ pub enum SnapshotCreationDeletionData {
PoolCategory(PoolCategoryResource),
}
impl WithBaseURL for SnapshotCreationDeletionData {
fn with_base_url(self, url: &str) -> Self {
match self {
SnapshotCreationDeletionData::Pool(pool) => {
SnapshotCreationDeletionData::Pool(pool.with_base_url(url))
}
SnapshotCreationDeletionData::Post(post) => {
SnapshotCreationDeletionData::Post(post.with_base_url(url))
}
_ => self,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
/// Data for a modified resource
@ -940,6 +1083,17 @@ pub enum SnapshotData {
Merge(Vec<String>),
}
impl WithBaseURL for SnapshotData {
fn with_base_url(self, url: &str) -> Self {
match self {
SnapshotData::CreateOrDelete(cod) => {
SnapshotData::CreateOrDelete(cod.with_base_url(url))
}
_ => self,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
/// Overall type representing some sort of change to a resource
@ -959,6 +1113,16 @@ pub struct SnapshotResource {
pub time: Option<DateTime<Utc>>,
}
impl WithBaseURL for SnapshotResource {
fn with_base_url(self, url: &str) -> Self {
SnapshotResource {
user: self.user.with_base_url(url),
data: self.data.with_base_url(url),
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
/// A result when searching for similar posts to a given image
@ -969,6 +1133,15 @@ pub struct ImageSearchSimilarPost {
pub post: PostResource,
}
impl WithBaseURL for ImageSearchSimilarPost {
fn with_base_url(self, url: &str) -> Self {
Self {
post: self.post.with_base_url(url),
..self
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
/// A type to represent the result from an Image search request
@ -981,6 +1154,15 @@ pub struct ImageSearchResult {
pub similar_posts: Vec<ImageSearchSimilarPost>,
}
impl WithBaseURL for ImageSearchResult {
fn with_base_url(self, url: &str) -> Self {
Self {
exact_post: self.exact_post.with_base_url(url),
similar_posts: self.similar_posts.with_base_url(url),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
/// A type that represents posts that are before or after an existing post
pub struct AroundPostResult {