use serde::{Deserialize, Serialize};
use crate::{field_access, impl_default, impl_display, Error, Result};
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Response {
#[serde(skip_serializing_if = "Option::is_none")]
uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
filename: Option<String>,
}
field_access! {
Response {
uri: option_cow_deref { str, String },
url: option_cow_deref { str, String },
filename: option_cow_deref { str, String },
}
}
impl Response {
pub fn realm_id(&self) -> Result<u64> {
self.url
.as_deref()
.and_then(|url| url.strip_prefix("/user_uploads/"))
.ok_or(Error::io_other("invalid upload URL"))
.and_then(|url| {
url.chars()
.take_while(|c| c.is_ascii_digit())
.collect::<String>()
.parse::<u64>()
.map_err(Error::from)
})
}
pub fn filename_path(&self) -> Result<String> {
self.url
.as_deref()
.and_then(|url| url.strip_prefix("/user_uploads/"))
.ok_or(Error::io_other("invalid upload URL"))
.map(|url| {
url.chars()
.skip_while(|c| c.is_ascii_digit() || c.is_ascii_hexdigit())
.skip_while(|c| c == &'/')
.collect::<String>()
})
}
}
impl Response {
pub const fn new() -> Self {
Self {
uri: None,
url: None,
filename: None,
}
}
}
impl_default!(Response);
impl_display!(Response);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_success_upload_file_response() {
let uri = "/test/uri";
let uri_json = serde_json::to_string(&uri).unwrap();
let url = "/test/url";
let url_json = serde_json::to_string(&url).unwrap();
let filename = "/test/filename";
let filename_json = serde_json::to_string(&filename).unwrap();
let response = Response::new()
.with_uri(uri)
.with_url(url)
.with_filename(filename);
let response_json =
format!(r#"{{"uri":{uri_json},"url":{url_json},"filename":{filename_json}}}"#);
assert_eq!(serde_json::to_string(&response).unwrap(), response_json);
assert_eq!(
serde_json::from_str::<Response>(&response_json).unwrap(),
response
);
assert_eq!(response.uri(), Some(uri));
assert_eq!(response.url(), Some(url));
assert_eq!(response.filename(), Some(filename));
}
}