1
0
Fork 0
mirror of https://github.com/Nutomic/ibis.git synced 2025-02-04 21:44:41 +00:00
ibis/src/backend/utils.rs

118 lines
3.7 KiB
Rust
Raw Normal View History

use crate::{
backend::error::MyResult,
common::{utils, utils::extract_domain, EditVersion, EditView},
};
use activitypub_federation::{fetch::object_id::ObjectId, traits::Object};
2023-11-27 15:34:45 +00:00
use anyhow::anyhow;
use diffy::{apply, Patch};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
2024-02-13 12:09:45 +00:00
use serde::Deserialize;
use url::{ParseError, Url};
2024-02-13 12:09:45 +00:00
pub fn generate_activity_id<T>(for_url: &ObjectId<T>) -> Result<Url, ParseError>
where
T: Object + Send + 'static,
for<'de2> <T as Object>::Kind: Deserialize<'de2>,
{
let domain = extract_domain(for_url);
let id: String = thread_rng()
.sample_iter(&Alphanumeric)
.take(7)
.map(char::from)
.collect();
2024-02-15 10:17:38 +00:00
Url::parse(&format!(
"{}://{}/objects/{}",
utils::http_protocol_str(),
domain,
id
))
}
2023-11-27 15:34:45 +00:00
/// Starting from empty string, apply edits until the specified version is reached. If no version is
/// given, apply all edits up to latest version.
///
/// TODO: testing
/// TODO: should cache all these generated versions
pub fn generate_article_version(edits: &Vec<EditView>, version: &EditVersion) -> MyResult<String> {
2023-11-27 15:34:45 +00:00
let mut generated = String::new();
2023-12-01 13:04:51 +00:00
if version == &EditVersion::default() {
return Ok(generated);
}
2023-11-27 15:34:45 +00:00
for e in edits {
let patch = Patch::from_str(&e.edit.diff)?;
2023-11-27 15:34:45 +00:00
generated = apply(&generated, &patch)?;
if &e.edit.hash == version {
2023-11-27 15:34:45 +00:00
return Ok(generated);
}
}
2023-11-28 12:04:33 +00:00
Err(anyhow!("failed to generate article version").into())
2023-11-27 15:34:45 +00:00
}
2023-12-05 11:54:38 +00:00
#[cfg(test)]
mod test {
use super::*;
use crate::common::{DbEdit, DbPerson};
2023-12-05 11:54:38 +00:00
use activitypub_federation::fetch::object_id::ObjectId;
use chrono::Utc;
2023-12-05 11:54:38 +00:00
use diffy::create_patch;
fn create_edits() -> MyResult<Vec<EditView>> {
let generate_edit = |a, b| -> MyResult<EditView> {
2023-12-05 11:54:38 +00:00
let diff = create_patch(a, b).to_string();
Ok(EditView {
edit: DbEdit {
id: 0,
creator_id: 0,
hash: EditVersion::new(&diff),
ap_id: ObjectId::parse("http://example.com")?,
diff,
summary: String::new(),
article_id: 0,
previous_version_id: Default::default(),
created: Utc::now(),
},
creator: DbPerson {
id: 0,
username: "".to_string(),
2024-02-28 14:54:34 +00:00
ap_id: ObjectId::parse("http://example.com")?,
inbox_url: "".to_string(),
public_key: "".to_string(),
private_key: None,
last_refreshed_at: Default::default(),
local: false,
},
2023-12-05 11:54:38 +00:00
})
};
Ok([
generate_edit("", "test\n")?,
generate_edit("test\n", "sda\n")?,
generate_edit("sda\n", "123\n")?,
]
.to_vec())
}
#[test]
fn test_generate_article_version() -> MyResult<()> {
let edits = create_edits()?;
let generated = generate_article_version(&edits, &edits[1].edit.hash)?;
2023-12-05 11:54:38 +00:00
assert_eq!("sda\n", generated);
Ok(())
}
#[test]
fn test_generate_invalid_version() -> MyResult<()> {
let edits = create_edits()?;
2024-01-30 15:06:02 +00:00
let generated = generate_article_version(&edits, &EditVersion::new("invalid"));
2023-12-05 11:54:38 +00:00
assert!(generated.is_err());
Ok(())
}
#[test]
fn test_generate_first_version() -> MyResult<()> {
let edits = create_edits()?;
let generated = generate_article_version(&edits, &EditVersion::default())?;
assert_eq!("", generated);
Ok(())
}
}