about summary refs log tree commit diff
path: root/util/src/micropub.rs
diff options
context:
space:
mode:
Diffstat (limited to 'util/src/micropub.rs')
-rw-r--r--util/src/micropub.rs33
1 files changed, 25 insertions, 8 deletions
diff --git a/util/src/micropub.rs b/util/src/micropub.rs
index 6127079..9d2c525 100644
--- a/util/src/micropub.rs
+++ b/util/src/micropub.rs
@@ -98,8 +98,8 @@ pub struct Error {
     /// General kind of an error that occured.
     pub error: ErrorKind,
     /// A human-readable error description intended for application developers.
-    // TODO use Cow<'static, str> to save on heap allocations
-    pub error_description: String,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub error_description: Option<std::borrow::Cow<'static, str>>,
 }
 
 impl std::error::Error for Error {}
@@ -113,9 +113,13 @@ impl std::fmt::Display for Error {
         };
 
         f.write_str(&s)?;
-        f.write_str(" (")?;
-        f.write_str(&self.error_description)?;
-        f.write_str(")")
+        if let Some(desc) = self.error_description.as_deref() {
+            f.write_str(" (")?;
+            f.write_str(desc)?;
+            f.write_str(")")?;
+        };
+
+        Ok(())
     }
 }
 
@@ -124,21 +128,34 @@ impl From<serde_json::Error> for Error {
         use ErrorKind::*;
         Self {
             error: InvalidRequest,
-            error_description: err.to_string(),
+            error_description: Some(err.to_string().into()),
         }
     }
 }
 
 impl Error {
     /// Create a new Micropub error.
-    pub fn new(error: ErrorKind, error_description: &str) -> Self {
+    pub fn new(error: ErrorKind, error_description: String) -> Self {
+        Self {
+            error,
+            error_description: Some(error_description.into()),
+        }
+    }
+    /// Create a new Micropub error from a static string.
+    pub const fn from_static(error: ErrorKind, error_description: &'static str) -> Self {
         Self {
             error,
-            error_description: error_description.to_owned(),
+            error_description: Some(std::borrow::Cow::Borrowed(error_description))
         }
     }
 }
 
+impl From<ErrorKind> for Error {
+    fn from(error: ErrorKind) -> Self {
+        Self { error, error_description: None }
+    }
+}
+
 #[cfg(feature = "http")]
 impl From<&Error> for http::StatusCode {
     fn from(err: &Error) -> Self {