edgestore_repl/
http_client.rs1use std::io::Read;
9
10use serde::{Deserialize, Serialize};
11
12use edgestore::replication::{ReplicationProtocol, SegmentRef};
13use edgestore::EdgestoreError;
14
15#[derive(Serialize, Deserialize)]
17struct MerkleResponse {
18 root: Vec<u8>,
19}
20
21#[derive(Serialize, Deserialize)]
23struct SegmentEntry {
24 segment_id: u64,
25 segment_hash: Vec<u8>,
26}
27
28pub struct HttpReplicationClient {
32 base_url: String,
33}
34
35impl HttpReplicationClient {
36 pub fn new(base_url: impl Into<String>) -> Self {
38 HttpReplicationClient {
39 base_url: base_url.into(),
40 }
41 }
42}
43
44impl ReplicationProtocol for HttpReplicationClient {
45 fn merkle_root(&self) -> Result<[u8; 32], EdgestoreError> {
50 let url = format!("{}/merkle", self.base_url);
51 let response = ureq::get(&url)
52 .call()
53 .map_err(|e| EdgestoreError::ReplicationError(format!("GET /merkle: {}", e)))?;
54
55 let resp: MerkleResponse = rmp_serde::from_read(response.into_reader())
56 .map_err(|e| EdgestoreError::ReplicationError(format!("GET /merkle decode: {}", e)))?;
57
58 if resp.root.len() != 32 {
59 return Err(EdgestoreError::ReplicationError(format!(
60 "GET /merkle: expected 32-byte root, got {} bytes",
61 resp.root.len()
62 )));
63 }
64
65 let mut hash = [0u8; 32];
66 hash.copy_from_slice(&resp.root);
67 Ok(hash)
68 }
69
70 fn list_segments(&self) -> Result<Vec<SegmentRef>, EdgestoreError> {
75 let url = format!("{}/segments", self.base_url);
76 let response = ureq::get(&url)
77 .call()
78 .map_err(|e| EdgestoreError::ReplicationError(format!("GET /segments: {}", e)))?;
79
80 let entries: Vec<SegmentEntry> =
81 rmp_serde::from_read(response.into_reader()).map_err(|e| {
82 EdgestoreError::ReplicationError(format!("GET /segments decode: {}", e))
83 })?;
84
85 let refs = entries
86 .into_iter()
87 .map(|e| {
88 let mut hash = [0u8; 32];
89 let copy_len = e.segment_hash.len().min(32);
90 hash[..copy_len].copy_from_slice(&e.segment_hash[..copy_len]);
91 SegmentRef {
92 segment_hash: hash,
93 segment_id: e.segment_id,
94 }
95 })
96 .collect();
97
98 Ok(refs)
99 }
100
101 fn fetch_segment(&self, hash: &[u8; 32]) -> Result<Vec<u8>, EdgestoreError> {
106 let hash_hex: String = hash.iter().map(|b| format!("{:02x}", b)).collect();
107 let url = format!("{}/segments/{}", self.base_url, hash_hex);
108
109 let response = ureq::get(&url).call().map_err(|e| {
110 EdgestoreError::ReplicationError(format!("GET /segments/{}: {}", hash_hex, e))
111 })?;
112
113 let mut data = Vec::new();
114 response.into_reader().read_to_end(&mut data).map_err(|e| {
115 EdgestoreError::ReplicationError(format!("GET /segments/{} read body: {}", hash_hex, e))
116 })?;
117
118 Ok(data)
119 }
120}