saleor-apps-rs/sitemap-generator/src/sitemap/mod.rs

129 lines
3.4 KiB
Rust
Raw Normal View History

2024-07-14 20:28:21 +00:00
pub mod event_handler;
pub mod regenerate;
2024-07-03 14:07:04 +00:00
2024-07-10 21:51:59 +00:00
use std::ops::{Deref, DerefMut};
2024-07-03 14:07:04 +00:00
use serde::{Deserialize, Serialize};
2024-07-10 21:51:59 +00:00
use tinytemplate::TinyTemplate;
use tracing::debug;
2024-07-10 21:51:59 +00:00
2024-07-14 20:28:21 +00:00
use crate::app::SitemapConfig;
2024-07-03 14:07:04 +00:00
const SITEMAP_XMLNS: &str = "http://sitemaps.org/schemas/sitemap/0.9";
const SALEOR_REF_XMLNS: &str = "http://app-sitemap-generator.kremik.sk/xml-schemas/saleor-ref.xsd";
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
2024-07-03 14:07:04 +00:00
#[serde(rename = "urlset")]
pub struct UrlSet {
2024-07-10 21:51:59 +00:00
pub urls: Vec<Url>,
2024-07-03 14:07:04 +00:00
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
2024-07-03 14:07:04 +00:00
pub struct Url {
2024-07-10 21:51:59 +00:00
pub url: String,
pub data: ItemData,
pub related: Option<ItemData>,
2024-07-03 14:07:04 +00:00
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
2024-07-10 21:51:59 +00:00
pub struct ItemData {
pub id: String,
pub slug: String,
pub typ: ItemType,
}
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
pub enum ItemType {
2024-07-03 14:07:04 +00:00
Product,
Category,
Collection,
Page,
2024-07-03 14:07:04 +00:00
}
impl UrlSet {
pub fn new() -> Self {
2024-07-10 21:51:59 +00:00
Self { urls: vec![] }
}
2024-07-11 17:21:50 +00:00
pub fn flush_related(&mut self, id: &str) {
self.retain(|u| u.data.id != id && u.related.as_ref().map_or(true, |ud| ud.id != id));
}
pub fn find_related(&mut self, id: &str) -> Vec<&mut Url> {
self.iter_mut()
.filter(|u| u.data.id == id || u.related.as_ref().map_or(false, |ud| ud.id == id))
.collect()
}
pub fn find_affected(&mut self, id: &str, slug: &str) -> Vec<&mut Url> {
self.iter_mut()
.filter(|u| {
debug!(
"comparing: ( {} == {} && {} != {} ) || ( {:?} == {} && {:?} != {} )",
&u.data.id,
&id,
&u.data.slug,
&slug,
u.related.clone().map(|ud| ud.id),
&id,
u.related.clone().map(|ud| ud.slug),
&slug
);
(u.data.id == id && u.data.slug != slug)
|| (u
.related
2024-07-11 17:21:50 +00:00
.as_ref()
.map_or(false, |ud| ud.id == id && ud.slug != slug))
2024-07-11 17:21:50 +00:00
})
.collect()
}
2024-07-10 21:51:59 +00:00
}
impl Deref for UrlSet {
type Target = Vec<Url>;
fn deref(&self) -> &Self::Target {
&self.urls
2024-07-03 14:07:04 +00:00
}
2024-07-10 21:51:59 +00:00
}
2024-07-10 21:51:59 +00:00
impl DerefMut for UrlSet {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.urls
}
2024-07-03 14:07:04 +00:00
}
impl Url {
2024-07-14 20:28:21 +00:00
pub fn new<T: Serialize>(
data: T,
sitemap_config: &SitemapConfig,
item: ItemData,
rel_item: Option<ItemData>,
) -> Result<Self, NewUrlError> {
2024-07-10 21:51:59 +00:00
let mut tt = TinyTemplate::new();
2024-07-14 20:28:21 +00:00
tt.add_template(
"t",
match item.typ {
ItemType::Category => &sitemap_config.category_template,
ItemType::Page => &sitemap_config.pages_template,
ItemType::Collection => &sitemap_config.collection_template,
ItemType::Product => &sitemap_config.product_template,
},
)?;
let url = tt.render("t", &data)?;
2024-07-10 21:51:59 +00:00
Ok(Self {
url,
2024-07-14 20:28:21 +00:00
data: item,
related: rel_item,
2024-07-10 21:51:59 +00:00
})
}
}
#[derive(thiserror::Error, Debug)]
pub enum NewUrlError {
#[error("Some property inside passed data for new url was None, but should've been Some")]
MissingData,
#[error("Bad templates or wrong context data to fill out the template")]
BadTemplating(#[from] tinytemplate::error::Error),
2024-07-03 14:07:04 +00:00
}