use chrono::{DateTime, Utc};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use crate::{NativeId, SourceError};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
pub struct Comment {
pub id: NativeId,
pub author: Option<String>,
pub created_at: Option<DateTime<Utc>>,
pub updated_at: Option<DateTime<Utc>>,
pub body: String,
pub url: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(try_from = "String", into = "String")]
pub struct CommentBody(String);
impl CommentBody {
pub fn new(text: impl Into<String>) -> Result<Self, SourceError> {
let text = text.into();
if text.is_empty() {
return Err(SourceError::Refused {
message: "a comment body cannot be empty; write what the comment says".to_owned(),
});
}
Ok(Self(text))
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
impl TryFrom<String> for CommentBody {
type Error = String;
fn try_from(text: String) -> Result<Self, Self::Error> {
Self::new(text).map_err(|error| error.to_string())
}
}
impl From<CommentBody> for String {
fn from(body: CommentBody) -> Self {
body.0
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct NewComment {
pub body: CommentBody,
#[serde(default)]
pub author: Option<String>,
}
#[must_use]
pub fn commentless(kind: &str) -> SourceError {
SourceError::Refused {
message: format!("the {kind} plugin has no comments"),
}
}