@@ -96,6 +96,13 @@ private func formatByteSize(_ value: Double) -> String? {
96 return ByteCountFormatter.string(fromByteCount: Int64(value), countStyle: .file)
96 return ByteCountFormatter.string(fromByteCount: Int64(value), countStyle: .file)
99+private func formatByteSize(_ value: Int) -> String? {
100+ // A negative byte count isn't meaningful; `ByteCountFormatter` would render it
101+ // as a bogus "-1 KB"/"Zero KB" string, so drop it like the `Double` path does.
102+ guard value >= 0 else { return nil }
103+ return ByteCountFormatter.string(fromByteCount: Int64(value), countStyle: .file)
99struct StreamStats: Codable, Sendable {
106struct StreamStats: Codable, Sendable {
100 let ingestion: IngestionStats?
107 let ingestion: IngestionStats?
101 let storage: StorageStats?
108 let storage: StorageStats?
@@ -118,7 +125,7 @@ struct StreamStats: Codable, Sendable {
118 if let s = try? container.decode(String.self, forKey: .size) {
125 if let s = try? container.decode(String.self, forKey: .size) {
119 self.size = s
126 self.size = s
120 } else if let n = try? container.decode(Int.self, forKey: .size) {
127 } else if let n = try? container.decode(Int.self, forKey: .size) {
121− self.size = ByteCountFormatter.string(fromByteCount: Int64(n), countStyle: .file)
128+ self.size = formatByteSize(n)
122 } else if let d = try? container.decode(Double.self, forKey: .size) {
129 } else if let d = try? container.decode(Double.self, forKey: .size) {
123 self.size = formatByteSize(d)
130 self.size = formatByteSize(d)
@@ -127,7 +134,7 @@ struct StreamStats: Codable, Sendable {
127 if let s = try? container.decode(String.self, forKey: .lifetime_size) {
134 if let s = try? container.decode(String.self, forKey: .lifetime_size) {
128 self.lifetime_size = s
135 self.lifetime_size = s
129 } else if let n = try? container.decode(Int.self, forKey: .lifetime_size) {
136 } else if let n = try? container.decode(Int.self, forKey: .lifetime_size) {
130− self.lifetime_size = ByteCountFormatter.string(fromByteCount: Int64(n), countStyle: .file)
137+ self.lifetime_size = formatByteSize(n)
131 } else if let d = try? container.decode(Double.self, forKey: .lifetime_size) {
138 } else if let d = try? container.decode(Double.self, forKey: .lifetime_size) {
132 self.lifetime_size = formatByteSize(d)
139 self.lifetime_size = formatByteSize(d)
@@ -151,7 +158,7 @@ struct StreamStats: Codable, Sendable {
151 if let s = try? container.decode(String.self, forKey: .size) {
158 if let s = try? container.decode(String.self, forKey: .size) {
152 self.size = s
159 self.size = s
153 } else if let n = try? container.decode(Int.self, forKey: .size) {
160 } else if let n = try? container.decode(Int.self, forKey: .size) {
154− self.size = ByteCountFormatter.string(fromByteCount: Int64(n), countStyle: .file)
161+ self.size = formatByteSize(n)
155 } else if let d = try? container.decode(Double.self, forKey: .size) {
162 } else if let d = try? container.decode(Double.self, forKey: .size) {
156 self.size = formatByteSize(d)
163 self.size = formatByteSize(d)
@@ -160,7 +167,7 @@ struct StreamStats: Codable, Sendable {
160 if let s = try? container.decode(String.self, forKey: .lifetime_size) {
167 if let s = try? container.decode(String.self, forKey: .lifetime_size) {
161 self.lifetime_size = s
168 self.lifetime_size = s
162 } else if let n = try? container.decode(Int.self, forKey: .lifetime_size) {
169 } else if let n = try? container.decode(Int.self, forKey: .lifetime_size) {
163− self.lifetime_size = ByteCountFormatter.string(fromByteCount: Int64(n), countStyle: .file)
170+ self.lifetime_size = formatByteSize(n)
164 } else if let d = try? container.decode(Double.self, forKey: .lifetime_size) {
171 } else if let d = try? container.decode(Double.self, forKey: .lifetime_size) {
165 self.lifetime_size = formatByteSize(d)
172 self.lifetime_size = formatByteSize(d)