Skip to main content

emv_3ds/message/
mod.rs

1pub mod areq;
2pub mod ares;
3pub mod creq;
4pub mod cres;
5pub mod error_msg;
6pub mod preq;
7pub mod pres;
8pub mod rreq;
9pub mod rres;
10
11pub use areq::AuthenticationRequest;
12pub use ares::AuthenticationResponse;
13pub use creq::ChallengeRequest;
14pub use cres::ChallengeResponse;
15pub use error_msg::ErrorMessage;
16pub use preq::PreparationRequest;
17pub use pres::{CardRangeData, PreparationResponse};
18pub use rreq::{MessageExtension, ResultsRequest};
19pub use rres::ResultsResponse;
20
21use serde::{Deserialize, Serialize};
22
23/// A type-erased EMV 3DS message, dispatched by the `messageType` field.
24#[derive(Debug, Clone)]
25pub enum Message {
26    AReq(Box<AuthenticationRequest>),
27    ARes(AuthenticationResponse),
28    CReq(ChallengeRequest),
29    CRes(ChallengeResponse),
30    Erro(ErrorMessage),
31    PReq(Box<PreparationRequest>),
32    PRes(PreparationResponse),
33    RReq(ResultsRequest),
34    RRes(ResultsResponse),
35}
36
37impl Message {
38    pub fn from_json(json: &str) -> crate::error::Result<Self> {
39        let peek: serde_json::Value = serde_json::from_str(json)?;
40        let tag = peek
41            .get("messageType")
42            .and_then(|v| v.as_str())
43            .ok_or(crate::error::Error::MissingField("messageType"))?;
44
45        match tag {
46            "AReq" => {
47                let m: AuthenticationRequest = serde_json::from_value(peek)?;
48                Ok(Self::AReq(Box::new(m)))
49            }
50            "ARes" => Ok(Self::ARes(serde_json::from_value(peek)?)),
51            "CReq" => Ok(Self::CReq(serde_json::from_value(peek)?)),
52            "CRes" => Ok(Self::CRes(serde_json::from_value(peek)?)),
53            "Erro" => Ok(Self::Erro(serde_json::from_value(peek)?)),
54            "PReq" => {
55                let m: PreparationRequest = serde_json::from_value(peek)?;
56                Ok(Self::PReq(Box::new(m)))
57            }
58            "PRes" => Ok(Self::PRes(serde_json::from_value(peek)?)),
59            "RReq" => Ok(Self::RReq(serde_json::from_value(peek)?)),
60            "RRes" => Ok(Self::RRes(serde_json::from_value(peek)?)),
61            other => Err(crate::error::Error::Protocol {
62                code: "405".to_owned(),
63                description: format!("unknown messageType: {other}"),
64            }),
65        }
66    }
67
68    pub fn to_json(&self) -> crate::error::Result<String> {
69        match self {
70            Self::AReq(m) => serde_json::to_string(m.as_ref()),
71            Self::ARes(m) => serde_json::to_string(m),
72            Self::CReq(m) => serde_json::to_string(m),
73            Self::CRes(m) => serde_json::to_string(m),
74            Self::Erro(m) => serde_json::to_string(m),
75            Self::PReq(m) => serde_json::to_string(m.as_ref()),
76            Self::PRes(m) => serde_json::to_string(m),
77            Self::RReq(m) => serde_json::to_string(m),
78            Self::RRes(m) => serde_json::to_string(m),
79        }
80        .map_err(Into::into)
81    }
82}
83
84impl Serialize for Message {
85    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
86        match self {
87            Self::AReq(m) => m.serialize(s),
88            Self::ARes(m) => m.serialize(s),
89            Self::CReq(m) => m.serialize(s),
90            Self::CRes(m) => m.serialize(s),
91            Self::Erro(m) => m.serialize(s),
92            Self::PReq(m) => m.serialize(s),
93            Self::PRes(m) => m.serialize(s),
94            Self::RReq(m) => m.serialize(s),
95            Self::RRes(m) => m.serialize(s),
96        }
97    }
98}
99
100impl<'de> Deserialize<'de> for Message {
101    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
102        let v = serde_json::Value::deserialize(d)?;
103        let tag = v
104            .get("messageType")
105            .and_then(|t| t.as_str())
106            .ok_or_else(|| serde::de::Error::missing_field("messageType"))?;
107
108        match tag {
109            "AReq" => serde_json::from_value::<AuthenticationRequest>(v)
110                .map(|m| Self::AReq(Box::new(m)))
111                .map_err(serde::de::Error::custom),
112            "ARes" => serde_json::from_value(v)
113                .map(Self::ARes)
114                .map_err(serde::de::Error::custom),
115            "CReq" => serde_json::from_value(v)
116                .map(Self::CReq)
117                .map_err(serde::de::Error::custom),
118            "CRes" => serde_json::from_value(v)
119                .map(Self::CRes)
120                .map_err(serde::de::Error::custom),
121            "Erro" => serde_json::from_value(v)
122                .map(Self::Erro)
123                .map_err(serde::de::Error::custom),
124            "PReq" => serde_json::from_value::<PreparationRequest>(v)
125                .map(|m| Self::PReq(Box::new(m)))
126                .map_err(serde::de::Error::custom),
127            "PRes" => serde_json::from_value(v)
128                .map(Self::PRes)
129                .map_err(serde::de::Error::custom),
130            "RReq" => serde_json::from_value(v)
131                .map(Self::RReq)
132                .map_err(serde::de::Error::custom),
133            "RRes" => serde_json::from_value(v)
134                .map(Self::RRes)
135                .map_err(serde::de::Error::custom),
136            other => Err(serde::de::Error::unknown_variant(
137                other,
138                &[
139                    "AReq", "ARes", "CReq", "CRes", "Erro", "PReq", "PRes", "RReq", "RRes",
140                ],
141            )),
142        }
143    }
144}