Skip to content

Commit

Permalink
Serialize text field for downgrade compatability
Browse files Browse the repository at this point in the history
  • Loading branch information
tarkah committed Jul 21, 2024
1 parent 2cc896e commit e0c91d2
Showing 1 changed file with 47 additions and 5 deletions.
52 changes: 47 additions & 5 deletions data/src/message.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::borrow::Cow;

use chrono::{DateTime, Utc};
use irc::proto;
use irc::proto::Command;
use itertools::Itertools;
use once_cell::sync::Lazy;
use regex::Regex;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -86,7 +89,7 @@ pub enum Direction {
Received,
}

#[derive(Debug, Clone, Serialize)]
#[derive(Debug, Clone)]
pub struct Message {
pub received_at: Posix,
pub server_time: DateTime<Utc>,
Expand Down Expand Up @@ -158,6 +161,35 @@ impl Message {
}
}

impl Serialize for Message {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct Data<'a> {
received_at: &'a Posix,
server_time: &'a DateTime<Utc>,
direction: &'a Direction,
target: &'a Target,
content: &'a Content,
// Old field before we had fragments,
// added for downgrade compatability
text: Cow<'a, str>,
}

Data {
received_at: &self.received_at,
server_time: &self.server_time,
direction: &self.direction,
target: &self.target,
content: &self.content,
text: self.content.text(),
}
.serialize(serializer)
}
}

impl<'de> Deserialize<'de> for Message {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand All @@ -169,7 +201,7 @@ impl<'de> Deserialize<'de> for Message {
server_time: DateTime<Utc>,
direction: Direction,
target: Target,
// New field
// New field, optional for upgrade compatability
content: Option<Content>,
// Old field before we had fragments
text: Option<String>,
Expand All @@ -184,10 +216,11 @@ impl<'de> Deserialize<'de> for Message {
text,
} = Data::deserialize(deserializer)?;

let content = if let Some(text) = text {
parse_fragments(text)
} else if let Some(content) = content {
let content = if let Some(content) = content {
content
} else if let Some(text) = text {
// First time upgrading, convert text into content
parse_fragments(text)
} else {
// Unreachable
Content::Plain("".to_string())
Expand Down Expand Up @@ -239,6 +272,15 @@ pub enum Content {
Fragments(Vec<Fragment>),
}

impl Content {
fn text(&self) -> Cow<str> {
match self {
Content::Plain(s) => s.into(),
Content::Fragments(fragments) => fragments.iter().map(Fragment::as_str).join("").into(),
}
}
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Fragment {
Text(String),
Expand Down

0 comments on commit e0c91d2

Please sign in to comment.