rl2tp/message/avp/types/
challenge_response.rs

1use crate::avp::{QueryableAVP, WritableAVP};
2use crate::common::{DecodeError, DecodeResult, Reader, Writer};
3use core::borrow::Borrow;
4
5const G_CHALLENGE_RESPONSE_LENGTH: usize = 16;
6
7#[derive(Clone, Debug, Eq, PartialEq)]
8pub struct ChallengeResponse {
9    pub value: [u8; G_CHALLENGE_RESPONSE_LENGTH],
10}
11
12impl ChallengeResponse {
13    const ATTRIBUTE_TYPE: u16 = 13;
14    const LENGTH: usize = G_CHALLENGE_RESPONSE_LENGTH;
15
16    #[inline]
17    pub fn try_read<T: Borrow<[u8]>>(reader: &mut impl Reader<T>) -> DecodeResult<Self> {
18        if reader.len() < Self::LENGTH {
19            return Err(DecodeError::IncompleteAVP(Self::ATTRIBUTE_TYPE));
20        }
21
22        Ok(Self {
23            value: reader
24                .bytes(16)
25                .ok_or(DecodeError::AVPReadError(Self::ATTRIBUTE_TYPE))?
26                .borrow()
27                .try_into()
28                .map_err(|_| DecodeError::IncompleteAVP(Self::ATTRIBUTE_TYPE))?,
29        })
30    }
31}
32
33impl From<[u8; G_CHALLENGE_RESPONSE_LENGTH]> for ChallengeResponse {
34    fn from(value: [u8; G_CHALLENGE_RESPONSE_LENGTH]) -> Self {
35        Self { value }
36    }
37}
38
39impl From<ChallengeResponse> for [u8; G_CHALLENGE_RESPONSE_LENGTH] {
40    fn from(value: ChallengeResponse) -> Self {
41        value.value
42    }
43}
44
45impl QueryableAVP for ChallengeResponse {
46    #[inline]
47    fn get_length(&self) -> usize {
48        Self::LENGTH
49    }
50}
51
52impl WritableAVP for ChallengeResponse {
53    #[inline]
54    fn write(&self, writer: &mut impl Writer) {
55        writer.write_u16_be(Self::ATTRIBUTE_TYPE);
56        writer.write_bytes(&self.value);
57    }
58}