Browse Source

Match Go ReplicaPlacement short string parsing with zero-padding

rust-volume-server
Chris Lu 3 days ago
parent
commit
2a981e539d
  1. 19
      seaweed-volume/src/storage/super_block.rs

19
seaweed-volume/src/storage/super_block.rs

@ -119,15 +119,21 @@ pub struct ReplicaPlacement {
impl ReplicaPlacement {
/// Parse from a string like "000", "010", "100".
/// Accepts 0-3 character strings, padding with leading zeros to match Go behavior.
/// E.g. "" -> "000", "1" -> "001", "01" -> "001", "010" -> "010"
pub fn from_string(s: &str) -> Result<Self, SuperBlockError> {
let s = s.trim();
if s.is_empty() {
return Ok(ReplicaPlacement::default());
}
if s.len() != 3 {
return Err(SuperBlockError::InvalidReplicaPlacement(s.to_string()));
}
let chars: Vec<char> = s.chars().collect();
// Pad with leading zeros to 3 chars, matching Go's NewReplicaPlacementFromString
let padded = match s.len() {
1 => format!("00{}", s),
2 => format!("0{}", s),
3 => s.to_string(),
_ => return Err(SuperBlockError::InvalidReplicaPlacement(s.to_string())),
};
let chars: Vec<char> = padded.chars().collect();
let dc = chars[0]
.to_digit(10)
.ok_or_else(|| SuperBlockError::InvalidReplicaPlacement(s.to_string()))?
@ -140,6 +146,11 @@ impl ReplicaPlacement {
.to_digit(10)
.ok_or_else(|| SuperBlockError::InvalidReplicaPlacement(s.to_string()))?
as u8;
// Go validates: value = dc*100 + rack*10 + same must fit in a byte
let value = dc as u16 * 100 + rack as u16 * 10 + same as u16;
if value > 255 {
return Err(SuperBlockError::InvalidReplicaPlacement(s.to_string()));
}
Ok(ReplicaPlacement {
diff_data_center_count: dc,
diff_rack_count: rack,

Loading…
Cancel
Save