radicle_ci_broker/
ci_event_source.rs

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
68
69
use std::fmt;

use radicle::Profile;

use crate::{
    ci_event::CiEvent,
    logger,
    node_event_source::{NodeEventError, NodeEventSource},
};

pub struct CiEventSource {
    source: NodeEventSource,
}

impl CiEventSource {
    pub fn new(profile: &Profile) -> Result<Self, CiEventSourceError> {
        let source = Self {
            source: NodeEventSource::new(profile).map_err(CiEventSourceError::Subscribe)?,
        };
        logger::ci_event_source_created(&source);
        Ok(source)
    }

    pub fn event(&mut self) -> Result<Option<Vec<CiEvent>>, CiEventSourceError> {
        let result = self.source.node_event();
        logger::debug2(format!("ci_event_source: result={result:?}"));
        match result {
            Err(err) if matches!(err, NodeEventError::BrokenConnection) => {
                logger::ci_event_source_disconnected();
                Err(CiEventSourceError::BrokenConnection(err))
            }
            Err(err) => {
                logger::error("error reading event from node", &err);
                Err(CiEventSourceError::NodeEventError(err))
            }
            Ok(None) => {
                logger::ci_event_source_end();
                Ok(None)
            }
            Ok(Some(event)) => {
                let ci_events =
                    CiEvent::from_node_event(&event).map_err(CiEventSourceError::CiEvent)?;
                logger::ci_event_source_got_events(&ci_events);
                Ok(Some(ci_events))
            }
        }
    }
}

impl fmt::Debug for CiEventSource {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "CiEventSource<path={:?}", self.source)
    }
}

#[derive(Debug, thiserror::Error)]
pub enum CiEventSourceError {
    #[error("failed to subscribe to node events")]
    Subscribe(#[source] crate::node_event_source::NodeEventError),

    #[error("connection to node control socket broke")]
    BrokenConnection(#[source] crate::node_event_source::NodeEventError),

    #[error("failed to read event from node")]
    NodeEventError(#[source] crate::node_event_source::NodeEventError),

    #[error("failed to create CI events from node event")]
    CiEvent(#[source] crate::ci_event::CiEventError),
}