monster_service/
export.rs1use edda_types::{
5 admin::MonstersExport,
6 rules_text::{ConditionText, SpellText},
7};
8use uuid::Uuid;
9
10use crate::{MonsterStore, error::ApiError, store, texts};
11
12impl MonsterStore {
13 pub async fn export_campaign(&self, campaign: Uuid) -> Result<MonstersExport, ApiError> {
15 Ok(MonstersExport {
16 monsters: self.export_own(campaign).await?,
17 spells: self.export_texts::<SpellText>(campaign).await?,
18 conditions: self.export_texts::<ConditionText>(campaign).await?,
19 })
20 }
21
22 pub async fn import_campaign(
26 &self,
27 campaign: Uuid,
28 export: &MonstersExport,
29 ) -> Result<u64, ApiError> {
30 let ours = Some(campaign);
31 if export.monsters.iter().any(|m| m.campaign != ours)
32 || export.spells.iter().any(|s| s.campaign != ours)
33 || export.conditions.iter().any(|c| c.campaign != ours)
34 {
35 return Err(ApiError::BadRequest(
36 "the export holds what isn't this campaign's own".into(),
37 ));
38 }
39 let mut tx = self.pool().begin().await?;
40 let (kept,): (i64,) = sqlx::query_as(
41 "SELECT (SELECT COUNT(*) FROM monsters WHERE campaign = $1) \
42 + (SELECT COUNT(*) FROM rules_text WHERE campaign = $1)",
43 )
44 .bind(campaign)
45 .fetch_one(&mut *tx)
46 .await?;
47 if kept > 0 {
48 return Err(ApiError::Conflict(format!(
49 "campaign {campaign} has {kept} monster(s), spell(s) or condition(s) here already"
50 )));
51 }
52 for monster in &export.monsters {
53 store::insert_as_is(&mut *tx, monster).await?;
54 }
55 for spell in &export.spells {
56 texts::insert_as_is(&mut *tx, spell).await?;
57 }
58 for condition in &export.conditions {
59 texts::insert_as_is(&mut *tx, condition).await?;
60 }
61 tx.commit().await?;
62 let count = export.monsters.len() + export.spells.len() + export.conditions.len();
63 Ok(u64::try_from(count).unwrap_or(u64::MAX))
64 }
65}