diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 6b77507d0..261c67b5e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -140,6 +140,10 @@ pub enum McapError { ChunkBufferTooLarge(u64), #[error("length exceeds usize max: `{0}`")] TooLong(u64), + #[error("cannot write more than 65335 channels to one MCAP")] + TooManyChannels, + #[error("cannot write more than 65334 schemas to one MCAP")] + TooManySchemas, } pub type McapResult = Result; diff --git a/rust/src/write.rs b/rust/src/write.rs index c4f9d1a5e..48bd04774 100644 --- a/rust/src/write.rs +++ b/rust/src/write.rs @@ -280,14 +280,20 @@ impl Writer { }) { return Ok(id); } + while self.schemas.contains_right(&self.next_schema_id) { + if self.next_schema_id == u16::MAX { + return Err(McapError::TooManySchemas); + } + self.next_schema_id += 1; + } let id = self.next_schema_id; + self.next_schema_id += 1; self.write_schema(Schema { id, name: name.into(), encoding: encoding.into(), data: Cow::Owned(data.into()), })?; - self.next_schema_id += 1; Ok(id) } @@ -347,12 +353,19 @@ impl Writer { }) { return Ok(id); } - let id = self.next_channel_id; - self.next_channel_id += 1; if schema_id != 0 && self.schemas.get_by_right(&schema_id).is_none() { return Err(McapError::UnknownSchema(topic.into(), schema_id)); } + while self.channels.contains_right(&self.next_channel_id) { + if self.next_channel_id == u16::MAX { + return Err(McapError::TooManyChannels); + } + self.next_channel_id += 1; + } + let id = self.next_channel_id; + self.next_channel_id += 1; + self.write_channel(records::Channel { id, schema_id,