use qrcode::{bits::Bits, EcLevel, QrCode, Version};
use ruma::serde::Base64;
use vodozemac::Ed25519PublicKey;
use crate::error::EncodingError;
pub(crate) const HEADER: &[u8] = b"MATRIX";
pub(crate) const VERSION: u8 = 0x2;
pub(crate) const MAX_MODE: u8 = 0x2;
pub(crate) const MIN_SECRET_LEN: usize = 8;
pub(crate) fn to_bytes(
mode: u8,
flow_id: &str,
first_key: Ed25519PublicKey,
second_key: Ed25519PublicKey,
shared_secret: &Base64,
) -> Result<Vec<u8>, EncodingError> {
let flow_id_len: u16 = flow_id.len().try_into()?;
let flow_id_len = flow_id_len.to_be_bytes();
let data = [
HEADER,
&[VERSION],
&[mode],
flow_id_len.as_ref(),
flow_id.as_bytes(),
first_key.as_bytes(),
second_key.as_bytes(),
shared_secret.as_bytes(),
]
.concat();
Ok(data)
}
pub(crate) fn to_qr_code(
mode: u8,
flow_id: &str,
first_key: Ed25519PublicKey,
second_key: Ed25519PublicKey,
shared_secret: &Base64,
) -> Result<QrCode, EncodingError> {
let data = to_bytes(mode, flow_id, first_key, second_key, shared_secret)?;
let mut bits = Bits::new(Version::Normal(7));
bits.push_byte_data(&data)?;
bits.push_terminator(EcLevel::L)?;
Ok(QrCode::with_bits(bits, EcLevel::L)?)
}