From 2a981e539dfa46a130380b7fae2723196561e2e2 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 16 Mar 2026 17:43:20 -0700 Subject: [PATCH] Match Go ReplicaPlacement short string parsing with zero-padding --- seaweed-volume/src/storage/super_block.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/seaweed-volume/src/storage/super_block.rs b/seaweed-volume/src/storage/super_block.rs index 8de269366..1a3a2140f 100644 --- a/seaweed-volume/src/storage/super_block.rs +++ b/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 { 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 = 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 = 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,