use crate::Article;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub enum EventType {
#[serde(rename = "update")]
Update,
#[serde(rename = "delete")]
Delete,
#[serde(rename = "visibility-change")]
VisibilityChange,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct EventMetadata {
pub identifier: String,
#[serde(rename = "type")]
pub event_type: EventType,
pub date_created: DateTime<Utc>,
pub date_published: Option<DateTime<Utc>>,
pub partition: Option<u32>,
pub offset: Option<u64>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Namespace {
pub identifier: u32,
pub name: Option<String>,
pub description: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Language {
pub identifier: Option<String>,
pub name: Option<String>,
pub alternate_name: Option<String>,
pub direction: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Project {
pub identifier: String,
pub url: String,
#[serde(rename = "type")]
pub project_type: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct ProjectInfo {
pub identifier: String,
pub code: Option<String>,
pub name: Option<String>,
pub url: Option<String>,
pub in_language: Option<Language>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct ProjectType {
pub identifier: String,
pub name: String,
pub description: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct Size {
pub unit_text: String,
pub value: f64,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct SnapshotInfo {
pub identifier: String,
pub version: String,
pub date_modified: DateTime<Utc>,
pub in_language: Language,
pub is_part_of: ProjectInfo,
pub namespace: Namespace,
pub size: Size,
pub chunks: Option<Vec<String>>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct ChunkInfo {
pub identifier: String,
pub version: String,
pub date_modified: DateTime<Utc>,
pub in_language: Language,
pub is_part_of: ProjectInfo,
pub namespace: Namespace,
pub size: Size,
pub url: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct SimplifiedLanguage {
pub identifier: String,
pub name: String,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct RealtimeProject {
pub identifier: String,
pub name: String,
pub url: String,
pub version: String,
pub date_modified: DateTime<Utc>,
pub size: Size,
pub in_language: SimplifiedLanguage,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct SimplifiedNamespace {
pub identifier: u32,
pub name: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct RealtimeBatchInfo {
pub identifier: String,
pub name: String,
pub version: String,
pub in_language: Language,
pub is_part_of: ProjectInfo,
pub namespace: Namespace,
pub size: Size,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct BatchInfo {
pub identifier: String,
pub date_created: DateTime<Utc>,
pub event_count: u64,
}
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
pub struct ArticleUpdate {
pub event_type: EventType,
pub article: Article,
pub event_metadata: EventMetadata,
}
#[cfg(test)]
mod tests {
use super::*;
use chrono::Utc;
#[test]
fn test_event_type_variants() {
let update = EventType::Update;
let delete = EventType::Delete;
let visibility = EventType::VisibilityChange;
assert!(matches!(update, EventType::Update));
assert!(matches!(delete, EventType::Delete));
assert!(matches!(visibility, EventType::VisibilityChange));
}
#[test]
fn test_event_metadata() {
let event = EventMetadata {
identifier: "evt-12345".to_string(),
event_type: EventType::Update,
date_created: Utc::now(),
date_published: Some(Utc::now()),
partition: Some(4),
offset: Some(3593806),
};
assert_eq!(event.identifier, "evt-12345");
assert_eq!(event.partition, Some(4));
assert_eq!(event.offset, Some(3593806));
}
#[test]
fn test_namespace_creation() {
let ns = Namespace {
identifier: 0,
name: Some("".to_string()),
description: Some("Main namespace".to_string()),
};
assert_eq!(ns.identifier, 0);
assert_eq!(ns.name, Some("".to_string()));
}
#[test]
fn test_language_creation() {
let lang = Language {
identifier: Some("en".to_string()),
name: Some("English".to_string()),
alternate_name: None,
direction: Some("ltr".to_string()),
};
assert_eq!(lang.identifier, Some("en".to_string()));
assert_eq!(lang.direction, Some("ltr".to_string()));
}
#[test]
fn test_rtl_language() {
let lang = Language {
identifier: Some("ar".to_string()),
name: Some("Arabic".to_string()),
alternate_name: Some("العربية".to_string()),
direction: Some("rtl".to_string()),
};
assert_eq!(lang.identifier, Some("ar".to_string()));
assert_eq!(lang.direction, Some("rtl".to_string()));
}
#[test]
fn test_project_info() {
let project = ProjectInfo {
identifier: "enwiki".to_string(),
code: Some("wikipedia".to_string()),
name: Some("English Wikipedia".to_string()),
url: Some("https://en.wikipedia.org".to_string()),
in_language: Some(Language {
identifier: Some("en".to_string()),
name: Some("English".to_string()),
alternate_name: None,
direction: Some("ltr".to_string()),
}),
};
assert_eq!(project.identifier, "enwiki");
assert_eq!(project.code, Some("wikipedia".to_string()));
}
#[test]
fn test_size() {
let size = Size {
unit_text: "MB".to_string(),
value: 1500.0,
};
assert_eq!(size.value, 1500.0);
assert_eq!(size.unit_text, "MB");
}
#[test]
fn test_snapshot_info() {
let snapshot = SnapshotInfo {
identifier: "enwiki_namespace_0".to_string(),
version: "2024-01-15".to_string(),
date_modified: Utc::now(),
in_language: Language {
identifier: Some("en".to_string()),
name: Some("English".to_string()),
alternate_name: None,
direction: Some("ltr".to_string()),
},
is_part_of: ProjectInfo {
identifier: "enwiki".to_string(),
code: Some("wikipedia".to_string()),
name: Some("English Wikipedia".to_string()),
url: Some("https://en.wikipedia.org".to_string()),
in_language: Some(Language {
identifier: Some("en".to_string()),
name: Some("English".to_string()),
alternate_name: None,
direction: Some("ltr".to_string()),
}),
},
namespace: Namespace {
identifier: 0,
name: Some("".to_string()),
description: Some("Main namespace".to_string()),
},
size: Size {
unit_text: "GB".to_string(),
value: 25.0,
},
chunks: Some(vec![]),
};
assert_eq!(snapshot.identifier, "enwiki_namespace_0");
assert_eq!(snapshot.chunks.as_ref().map(|v| v.len()).unwrap_or(0), 0);
}
}