Skip to main content

braid_core/core/server/
parse_update.rs

1//! Parse incoming update requests for Braid protocol.
2
3use crate::core::error::Result;
4use crate::core::protocol_mod as protocol;
5use crate::core::{Patch, Version};
6use axum::extract::Request;
7use bytes::Bytes;
8
9/// Parsed update from request body.
10#[derive(Clone, Debug)]
11pub struct ParsedUpdate {
12    /// Version ID(s) from Version header
13    pub version: Vec<Version>,
14    /// Parent version ID(s) from Parents header
15    pub parents: Vec<Version>,
16    /// Patches extracted from request body
17    pub patches: Vec<Patch>,
18    /// Full body if not patches (snapshot)
19    pub body: Option<Bytes>,
20}
21
22impl ParsedUpdate {
23    /// Create from HTTP request headers.
24    pub fn from_request_headers(req: &Request) -> Result<Self> {
25        let version_header = req
26            .headers()
27            .get("version")
28            .and_then(|v| v.to_str().ok())
29            .unwrap_or("");
30
31        let parents_header = req
32            .headers()
33            .get("parents")
34            .and_then(|v| v.to_str().ok())
35            .unwrap_or("");
36
37        let version = protocol::parse_version_header(version_header)?;
38        let parents = protocol::parse_version_header(parents_header)?;
39
40        Ok(ParsedUpdate {
41            version,
42            parents,
43            patches: Vec::new(),
44            body: None,
45        })
46    }
47}
48
49/// Extension trait for Axum request to parse Braid updates.
50pub trait ParseUpdateExt {
51    fn get_version(&self) -> Result<Vec<Version>>;
52    fn get_parents(&self) -> Result<Vec<Version>>;
53}
54
55impl ParseUpdateExt for Request {
56    fn get_version(&self) -> Result<Vec<Version>> {
57        let val = self
58            .headers()
59            .get("version")
60            .and_then(|v| v.to_str().ok())
61            .unwrap_or("");
62        Ok(protocol::parse_version_header(val)?)
63    }
64
65    fn get_parents(&self) -> Result<Vec<Version>> {
66        let val = self
67            .headers()
68            .get("parents")
69            .and_then(|v| v.to_str().ok())
70            .unwrap_or("");
71        Ok(protocol::parse_version_header(val)?)
72    }
73}