melib/jmap: fix blob download URL formatting
parent
48a10f7241
commit
6280bc75e5
|
@ -1284,6 +1284,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_path_to_error",
|
||||
"smallvec",
|
||||
"smol",
|
||||
"stderrlog",
|
||||
|
@ -1934,6 +1935,16 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_path_to_error"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha1_smol"
|
||||
version = "1.0.0"
|
||||
|
|
|
@ -71,7 +71,7 @@ regex = "1"
|
|||
tempfile = "3.3"
|
||||
|
||||
[features]
|
||||
default = ["sqlite3", "notmuch", "regexp", "smtp", "dbus-notifications", "gpgme", "cli-docs"]
|
||||
default = ["sqlite3", "notmuch", "regexp", "smtp", "dbus-notifications", "gpgme", "cli-docs", "jmap"]
|
||||
notmuch = ["melib/notmuch_backend", ]
|
||||
jmap = ["melib/jmap_backend",]
|
||||
sqlite3 = ["melib/sqlite3"]
|
||||
|
|
|
@ -207,7 +207,9 @@ impl MailBackend for PluginBackend {
|
|||
&mut self,
|
||||
_name: String,
|
||||
) -> ResultFuture<(MailboxHash, HashMap<MailboxHash, Mailbox>)> {
|
||||
Err(Error::new("Creating a mailbox is currently unimplemented for plugins"))
|
||||
Err(Error::new(
|
||||
"Creating a mailbox is currently unimplemented for plugins",
|
||||
))
|
||||
}
|
||||
fn collection(&self) -> melib::Collection {
|
||||
self.collection.clone()
|
||||
|
|
|
@ -40,9 +40,10 @@ nom = { version = "7" }
|
|||
notify = { version = "4.0.15", optional = true }
|
||||
regex = { version = "1" }
|
||||
rusqlite = { version = "^0.28", default-features = false, optional = true }
|
||||
serde = { version = "1.0.71", features = ["rc", ] }
|
||||
serde_derive = "1.0.71"
|
||||
serde = { version = "1.0", features = ["rc", ] }
|
||||
serde_derive = "1.0"
|
||||
serde_json = { version = "1.0", features = ["raw_value",] }
|
||||
serde_path_to_error = { version = "0.1" }
|
||||
smallvec = { version = "^1.5.0", features = ["serde", ] }
|
||||
smol = "1.0.0"
|
||||
|
||||
|
|
|
@ -84,6 +84,22 @@ use objects::*;
|
|||
pub mod mailbox;
|
||||
use mailbox::*;
|
||||
|
||||
pub fn deserialize_from_str<'de, T: serde::de::Deserialize<'de>>(s: &'de str) -> Result<T> {
|
||||
let jd = &mut serde_json::Deserializer::from_str(s);
|
||||
match serde_path_to_error::deserialize(jd) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(err) => Err(Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report this!\nError \
|
||||
{} at {}. Reply from server: {}",
|
||||
err,
|
||||
err.path(),
|
||||
&s
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug)),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct EnvelopeCache {
|
||||
bytes: Option<String>,
|
||||
|
@ -430,15 +446,8 @@ impl MailBackend for JmapType {
|
|||
};
|
||||
let res_text = res.text().await?;
|
||||
|
||||
let upload_response: UploadResponse = match serde_json::from_str(&res_text) {
|
||||
let upload_response: UploadResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -467,23 +476,15 @@ impl MailBackend for JmapType {
|
|||
.await?;
|
||||
let res_text = res.text().await?;
|
||||
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
Ok(s) => s,
|
||||
};
|
||||
let m = ImportResponse::try_from(v.method_responses.remove(0)).map_err(|err| {
|
||||
let ierr: Result<ImportError> =
|
||||
serde_json::from_str(&res_text).map_err(|err| err.into());
|
||||
let ierr: Result<ImportError> = deserialize_from_str(&res_text);
|
||||
if let Ok(err) = ierr {
|
||||
Error::new(format!("Could not save message: {:?}", err))
|
||||
} else {
|
||||
|
@ -554,15 +555,8 @@ impl MailBackend for JmapType {
|
|||
.await?;
|
||||
|
||||
let res_text = res.text().await?;
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -694,15 +688,8 @@ impl MailBackend for JmapType {
|
|||
|
||||
let res_text = res.text().await?;
|
||||
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -816,15 +803,8 @@ impl MailBackend for JmapType {
|
|||
* p-5;vfs-0"}
|
||||
*/
|
||||
//debug!("res_text = {}", &res_text);
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
|
|
@ -100,8 +100,8 @@ impl JmapConnection {
|
|||
jmap_session_resource_url = to_well_known(&self.server_conf.server_url);
|
||||
if let Ok(s) = self.client.get_async(&jmap_session_resource_url).await {
|
||||
log::error!(
|
||||
"Account {} server URL should start with `https`. Please correct \
|
||||
your configuration value. Its current value is `{}`.",
|
||||
"Account {} server URL should start with `https`. Please correct your \
|
||||
configuration value. Its current value is `{}`.",
|
||||
self.store.account_name,
|
||||
self.server_conf.server_url
|
||||
);
|
||||
|
@ -151,7 +151,7 @@ impl JmapConnection {
|
|||
Ok(s) => s,
|
||||
};
|
||||
|
||||
let session: JmapSession = match serde_json::from_str(&res_text) {
|
||||
let session: JmapSession = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"Could not connect to JMAP server endpoint for {}. Is your server url setting \
|
||||
|
@ -167,14 +167,36 @@ impl JmapConnection {
|
|||
Ok(s) => s,
|
||||
};
|
||||
if !session.capabilities.contains_key(JMAP_CORE_CAPABILITY) {
|
||||
let err = Error::new(format!("Server {} did not return JMAP Core capability ({core_capability}). Returned capabilities were: {}", &self.server_conf.server_url, session.capabilities.keys().map(String::as_str).collect::<Vec<&str>>().join(", "), core_capability=JMAP_CORE_CAPABILITY));
|
||||
let err = Error::new(format!(
|
||||
"Server {} did not return JMAP Core capability ({core_capability}). Returned \
|
||||
capabilities were: {}",
|
||||
&self.server_conf.server_url,
|
||||
session
|
||||
.capabilities
|
||||
.keys()
|
||||
.map(String::as_str)
|
||||
.collect::<Vec<&str>>()
|
||||
.join(", "),
|
||||
core_capability = JMAP_CORE_CAPABILITY
|
||||
));
|
||||
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
*self.store.core_capabilities.lock().unwrap() =
|
||||
session.capabilities[JMAP_CORE_CAPABILITY].clone();
|
||||
if !session.capabilities.contains_key(JMAP_MAIL_CAPABILITY) {
|
||||
let err = Error::new(format!("Server {} does not support JMAP Mail capability ({mail_capability}). Returned capabilities were: {}", &self.server_conf.server_url, session.capabilities.keys().map(String::as_str).collect::<Vec<&str>>().join(", "), mail_capability=JMAP_MAIL_CAPABILITY));
|
||||
let err = Error::new(format!(
|
||||
"Server {} does not support JMAP Mail capability ({mail_capability}). Returned \
|
||||
capabilities were: {}",
|
||||
&self.server_conf.server_url,
|
||||
session
|
||||
.capabilities
|
||||
.keys()
|
||||
.map(String::as_str)
|
||||
.collect::<Vec<&str>>()
|
||||
.join(", "),
|
||||
mail_capability = JMAP_MAIL_CAPABILITY
|
||||
));
|
||||
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -266,15 +288,8 @@ impl JmapConnection {
|
|||
|
||||
let res_text = res.text().await?;
|
||||
debug!(&res_text);
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please \
|
||||
report this!\nReply from server: {}",
|
||||
&self.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -446,11 +461,10 @@ impl JmapConnection {
|
|||
|
||||
let res_text = res.text().await?;
|
||||
debug!(&res_text);
|
||||
let _: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let _: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!("BUG: Could not deserialize {} server JSON response properly, please report this!\nReply from server: {}", &self.server_conf.server_url, &res_text)).set_source(Some(Arc::new(err))).set_kind(ErrorKind::Bug);
|
||||
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
log::error!("{}", &err);
|
||||
*self.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
Ok(s) => s,
|
||||
|
|
|
@ -337,7 +337,7 @@ impl std::convert::From<EmailObject> for crate::Envelope {
|
|||
pub struct HtmlBody {
|
||||
pub blob_id: Id<BlobObject>,
|
||||
#[serde(default)]
|
||||
pub charset: String,
|
||||
pub charset: Option<String>,
|
||||
#[serde(default)]
|
||||
pub cid: Option<String>,
|
||||
#[serde(default)]
|
||||
|
@ -364,7 +364,7 @@ pub struct HtmlBody {
|
|||
pub struct TextBody {
|
||||
pub blob_id: Id<BlobObject>,
|
||||
#[serde(default)]
|
||||
pub charset: String,
|
||||
pub charset: Option<String>,
|
||||
#[serde(default)]
|
||||
pub cid: Option<String>,
|
||||
#[serde(default)]
|
||||
|
@ -854,16 +854,9 @@ pub struct EmailQueryChangesResponse {
|
|||
|
||||
impl std::convert::TryFrom<&RawValue> for EmailQueryChangesResponse {
|
||||
type Error = crate::error::Error;
|
||||
fn try_from(t: &RawValue) -> Result<Self> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug)
|
||||
})?;
|
||||
|
||||
fn try_from(t: &RawValue) -> std::result::Result<Self, Self::Error> {
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, "Email/queryChanges");
|
||||
Ok(res.1)
|
||||
}
|
||||
|
|
|
@ -196,16 +196,9 @@ pub struct ImportResponse {
|
|||
|
||||
impl std::convert::TryFrom<&RawValue> for ImportResponse {
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn try_from(t: &RawValue) -> Result<Self> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug)
|
||||
})?;
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, &ImportCall::NAME);
|
||||
Ok(res.1)
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::*;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ThreadObject {
|
||||
|
|
|
@ -49,8 +49,7 @@ impl BackendOp for JmapOp {
|
|||
fn as_bytes(&mut self) -> ResultFuture<Vec<u8>> {
|
||||
{
|
||||
let byte_lck = self.store.byte_cache.lock().unwrap();
|
||||
if byte_lck.contains_key(&self.hash) && byte_lck[&self.hash].bytes.is_some() {
|
||||
let ret = byte_lck[&self.hash].bytes.clone().unwrap();
|
||||
if let Some(Some(ret)) = byte_lck.get(&self.hash).map(|c| c.bytes.clone()) {
|
||||
return Ok(Box::pin(async move { Ok(ret.into_bytes()) }));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ pub async fn get_mailboxes(conn: &JmapConnection) -> Result<HashMap<MailboxHash,
|
|||
}))?)
|
||||
.await?;
|
||||
|
||||
let mut v: MethodResponse = serde_json::from_str(&res_text).unwrap();
|
||||
let mut v: MethodResponse = deserialize_from_str(&res_text)?;
|
||||
*conn.store.online_status.lock().await = (std::time::Instant::now(), Ok(()));
|
||||
let m = GetResponse::<MailboxObject>::try_from(v.method_responses.remove(0))?;
|
||||
let GetResponse::<MailboxObject> {
|
||||
|
@ -191,15 +191,8 @@ pub async fn get_message_list(
|
|||
.await?;
|
||||
|
||||
let res_text = res.text().await?;
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await = (Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -259,7 +252,7 @@ impl EmailFetchState {
|
|||
let current_state_lck = mbox.email_state.lock().unwrap();
|
||||
(
|
||||
current_state_lck.is_none(),
|
||||
current_state_lck.as_ref() != Some(&state),
|
||||
current_state_lck.as_ref() == Some(&state),
|
||||
)
|
||||
})
|
||||
.unwrap_or((true, true))
|
||||
|
@ -324,15 +317,8 @@ impl EmailFetchState {
|
|||
|
||||
let _prev_seq = req.add_call(&email_call);
|
||||
let res_text = conn.send_request(serde_json::to_string(&req)?).await?;
|
||||
let mut v: MethodResponse = match serde_json::from_str(&res_text) {
|
||||
let mut v: MethodResponse = match deserialize_from_str(&res_text) {
|
||||
Err(err) => {
|
||||
let err = Error::new(format!(
|
||||
"BUG: Could not deserialize {} server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&conn.server_conf.server_url, &res_text
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(ErrorKind::Bug);
|
||||
*conn.store.online_status.lock().await =
|
||||
(Instant::now(), Err(err.clone()));
|
||||
return Err(err);
|
||||
|
|
|
@ -42,7 +42,7 @@ use std::collections::HashMap;
|
|||
|
||||
pub use argument::*;
|
||||
|
||||
use super::protocol::Method;
|
||||
use super::{deserialize_from_str, protocol::Method};
|
||||
pub trait Object {
|
||||
const NAME: &'static str;
|
||||
}
|
||||
|
@ -282,7 +282,6 @@ impl Object for BlobObject {
|
|||
/// - `account_id`: `Id`
|
||||
///
|
||||
/// The id of the account to use.
|
||||
///
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Get<OBJ>
|
||||
|
@ -427,16 +426,9 @@ pub struct GetResponse<OBJ: Object> {
|
|||
|
||||
impl<OBJ: Object + DeserializeOwned> std::convert::TryFrom<&RawValue> for GetResponse<OBJ> {
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn try_from(t: &RawValue) -> Result<Self, crate::error::Error> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(crate::error::ErrorKind::Bug)
|
||||
})?;
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, &format!("{}/get", OBJ::NAME));
|
||||
Ok(res.1)
|
||||
}
|
||||
|
@ -548,16 +540,9 @@ pub struct QueryResponse<OBJ: Object> {
|
|||
|
||||
impl<OBJ: Object + DeserializeOwned> std::convert::TryFrom<&RawValue> for QueryResponse<OBJ> {
|
||||
type Error = crate::error::Error;
|
||||
fn try_from(t: &RawValue) -> Result<Self, crate::error::Error> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(crate::error::ErrorKind::Bug)
|
||||
})?;
|
||||
|
||||
fn try_from(t: &RawValue) -> std::result::Result<Self, Self::Error> {
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, &format!("{}/query", OBJ::NAME));
|
||||
Ok(res.1)
|
||||
}
|
||||
|
@ -618,7 +603,6 @@ impl<M: Method<OBJ>, OBJ: Object> ResultField<M, OBJ> {
|
|||
/// to return. If supplied by the client, the value MUST be a
|
||||
/// positive integer greater than 0. If a value outside of this range
|
||||
/// is given, the server MUST re
|
||||
///
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
/* ch-ch-ch-ch-ch-Changes */
|
||||
|
@ -697,16 +681,9 @@ pub struct ChangesResponse<OBJ: Object> {
|
|||
|
||||
impl<OBJ: Object + DeserializeOwned> std::convert::TryFrom<&RawValue> for ChangesResponse<OBJ> {
|
||||
type Error = crate::error::Error;
|
||||
fn try_from(t: &RawValue) -> Result<Self, crate::error::Error> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(crate::error::ErrorKind::Bug)
|
||||
})?;
|
||||
|
||||
fn try_from(t: &RawValue) -> std::result::Result<Self, Self::Error> {
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, &format!("{}/changes", OBJ::NAME));
|
||||
Ok(res.1)
|
||||
}
|
||||
|
@ -911,16 +888,9 @@ pub struct SetResponse<OBJ: Object> {
|
|||
|
||||
impl<OBJ: Object + DeserializeOwned> std::convert::TryFrom<&RawValue> for SetResponse<OBJ> {
|
||||
type Error = crate::error::Error;
|
||||
|
||||
fn try_from(t: &RawValue) -> Result<Self, crate::error::Error> {
|
||||
let res: (String, Self, String) = serde_json::from_str(t.get()).map_err(|err| {
|
||||
crate::error::Error::new(format!(
|
||||
"BUG: Could not deserialize server JSON response properly, please report \
|
||||
this!\nReply from server: {}",
|
||||
&t
|
||||
))
|
||||
.set_source(Some(Arc::new(err)))
|
||||
.set_kind(crate::error::ErrorKind::Bug)
|
||||
})?;
|
||||
let res: (String, Self, String) = deserialize_from_str(t.get())?;
|
||||
assert_eq!(&res.0, &format!("{}/set", OBJ::NAME));
|
||||
Ok(res.1)
|
||||
}
|
||||
|
@ -1038,6 +1008,16 @@ pub fn download_request_format(
|
|||
} else if download_url[prev_pos..].starts_with("{name}") {
|
||||
ret.push_str(name.as_deref().unwrap_or(""));
|
||||
prev_pos += "{name}".len();
|
||||
} else if download_url[prev_pos..].starts_with("{type}") {
|
||||
ret.push_str("application/octet-stream");
|
||||
prev_pos += "{name}".len();
|
||||
} else {
|
||||
// [ref:FIXME]: return protocol error here
|
||||
log::error!(
|
||||
"BUG: unknown parameter in download url: {}",
|
||||
&download_url[prev_pos..]
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if prev_pos != download_url.len() {
|
||||
|
|
Loading…
Reference in New Issue