1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use std::sync::Arc;

use synd_o11y::metric;

use crate::{
    principal::Principal,
    repository::{self, SubscriptionRepository},
    usecase::{Input, Output},
};

use super::{authorize::Unauthorized, Usecase};

pub struct UnsubscribeFeed {
    pub repository: Arc<dyn SubscriptionRepository>,
}

pub struct UnsubscribeFeedInput {
    pub url: String,
}

pub struct UnsubscribeFeedOutput {}

impl Usecase for UnsubscribeFeed {
    type Input = UnsubscribeFeedInput;

    type Output = UnsubscribeFeedOutput;

    type Error = anyhow::Error;

    fn new(make: &super::MakeUsecase) -> Self {
        Self {
            repository: make.subscription_repo.clone(),
        }
    }

    async fn authorize(
        &self,
        principal: Principal,
        _: &UnsubscribeFeedInput,
    ) -> Result<Principal, Unauthorized> {
        Ok(principal)
    }

    async fn usecase(
        &self,
        Input {
            principal,
            input: UnsubscribeFeedInput { url },
            ..
        }: Input<Self::Input>,
    ) -> Result<Output<Self::Output>, super::Error<Self::Error>> {
        tracing::debug!("Unsubscribe feed: {url}");

        self.repository
            .delete_feed_subscription(repository::types::FeedSubscription {
                user_id: principal.user_id().unwrap().to_owned(),
                url,
            })
            .await?;

        metric!(monotonic_counter.feed.unsubscription = 1);

        Ok(Output {
            output: UnsubscribeFeedOutput {},
        })
    }
}