use sim_kernel::{Cx, Object, Result, Value};
pub const DOC_KIND_ARTICLE: &str = "article";
pub const DOC_KIND_REPORT: &str = "report";
pub const DOC_KIND_README: &str = "readme";
#[derive(Clone, Debug, PartialEq)]
pub struct Doc {
pub kind: DocKind,
pub id: DocId,
pub body: Value,
pub origin: Vec<ExternalRef>,
}
impl Doc {
#[must_use]
pub fn new(kind: DocKind, id: DocId, body: Value, origin: Vec<ExternalRef>) -> Self {
Self {
kind,
id,
body,
origin,
}
}
}
impl Object for Doc {
fn display(&self, _cx: &mut Cx) -> Result<String> {
Ok(format!("#<doc {} {}>", self.kind.0, self.id.0))
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl sim_kernel::ObjectCompat for Doc {}
#[derive(
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct DocKind(pub String);
impl DocKind {
#[must_use]
pub fn new(kind: impl Into<String>) -> Self {
Self(kind.into())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct DocId(pub String);
impl DocId {
#[must_use]
pub fn new(id: impl Into<String>) -> Self {
Self(id.into())
}
#[must_use]
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ExternalRef {
pub backend: String,
pub external_id: String,
pub version: Option<String>,
pub web_url: Option<String>,
}
impl ExternalRef {
#[must_use]
pub fn new(
backend: impl Into<String>,
external_id: impl Into<String>,
version: Option<String>,
web_url: Option<String>,
) -> Self {
Self {
backend: backend.into(),
external_id: external_id.into(),
version,
web_url,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn doc_json_round_trip() {
let refs = vec![ExternalRef::new(
"codec/plain",
"doc-1",
Some("rev-2".to_owned()),
Some("https://example.com/doc-1".to_owned()),
)];
let encoded = serde_json::to_string(&refs).unwrap();
let decoded: Vec<ExternalRef> = serde_json::from_str(&encoded).unwrap();
assert_eq!(decoded, refs);
}
#[test]
fn prose_kind_constants_are_reserved() {
assert_eq!(DocKind::new(DOC_KIND_ARTICLE).as_str(), "article");
assert_eq!(DocKind::new(DOC_KIND_REPORT).as_str(), "report");
assert_eq!(DocKind::new(DOC_KIND_README).as_str(), "readme");
}
}