tiberius/tds/codec/token/
token_feature_ext_ack.rs

1use crate::{SqlReadBytes, FEA_EXT_FEDAUTH, FEA_EXT_TERMINATOR};
2use futures_util::AsyncReadExt;
3
4#[derive(Debug)]
5pub struct TokenFeatureExtAck {
6    pub features: Vec<FeatureAck>,
7}
8
9#[derive(Debug)]
10#[allow(dead_code)]
11pub enum FedAuthAck {
12    SecurityToken { nonce: Option<[u8; 32]> },
13}
14
15#[derive(Debug)]
16#[allow(dead_code)]
17pub enum FeatureAck {
18    FedAuth(FedAuthAck),
19}
20
21impl TokenFeatureExtAck {
22    pub(crate) async fn decode<R>(src: &mut R) -> crate::Result<Self>
23    where
24        R: SqlReadBytes + Unpin,
25    {
26        let mut features = Vec::new();
27        loop {
28            let feature_id = src.read_u8().await?;
29
30            if feature_id == FEA_EXT_TERMINATOR {
31                break;
32            } else if feature_id == FEA_EXT_FEDAUTH {
33                let data_len = src.read_u32_le().await?;
34
35                let nonce = if data_len == 32 {
36                    let mut n = [0u8; 32];
37                    src.read_exact(&mut n).await?;
38
39                    Some(n)
40                } else if data_len == 0 {
41                    None
42                } else {
43                    panic!("invalid Feature_Ext_Ack token");
44                };
45
46                features.push(FeatureAck::FedAuth(FedAuthAck::SecurityToken { nonce }))
47            } else {
48                unimplemented!("unsupported feature {}", feature_id)
49            }
50        }
51
52        Ok(TokenFeatureExtAck { features })
53    }
54}