blueprint_tangle_extra/extract/
service_id.rs

1use blueprint_core::{
2    __composite_rejection as composite_rejection, __define_rejection as define_rejection,
3};
4use blueprint_core::{FromJobCallParts, job::call::Parts as JobCallParts};
5
6/// Extracts the current service id from the job call.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
8pub struct ServiceId(pub u64);
9
10impl ServiceId {
11    pub const METADATA_KEY: &'static str = "X-TANGLE-SERVICE-ID";
12}
13
14blueprint_core::__impl_deref!(ServiceId: u64);
15blueprint_core::__impl_from!(u64, ServiceId);
16
17define_rejection! {
18  #[body = "No ServiceId found in the metadata"]
19  /// A Rejection type for [`ServiceId`] when it is missing from the Metadata.
20  pub struct MissingServiceId;
21}
22
23define_rejection! {
24  #[body = "The service id in the metadata is not a valid integer"]
25  /// A Rejection type for [`ServiceId`] when it is not a valid u64.
26  pub struct InvalidServiceId;
27}
28
29composite_rejection! {
30    /// Rejection used for [`ServiceId`].
31    ///
32    /// Contains one variant for each way the [`ServiceId`] extractor
33    /// can fail.
34    pub enum ServiceIdRejection {
35        MissingServiceId,
36        InvalidServiceId,
37    }
38}
39
40impl TryFrom<&mut JobCallParts> for ServiceId {
41    type Error = ServiceIdRejection;
42
43    fn try_from(parts: &mut JobCallParts) -> Result<Self, Self::Error> {
44        let service_id_raw = parts
45            .metadata
46            .get(Self::METADATA_KEY)
47            .ok_or(MissingServiceId)?;
48        let service_id = service_id_raw.try_into().map_err(|_| InvalidServiceId)?;
49        Ok(ServiceId(service_id))
50    }
51}
52
53impl<Ctx> FromJobCallParts<Ctx> for ServiceId
54where
55    Ctx: Send + Sync,
56{
57    type Rejection = ServiceIdRejection;
58
59    async fn from_job_call_parts(
60        parts: &mut JobCallParts,
61        _: &Ctx,
62    ) -> Result<Self, Self::Rejection> {
63        Self::try_from(parts)
64    }
65}