Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
- Replaced 26 infallible-by-construction `.expect()` sites in `lading_payload`
with `.unwrap_or_else(|| unreachable!("..."))`, making the impossibility
structural and explicit. Sites covered: 20 `CONST_ARR.choose(rng)` against
non-empty `const` arrays, 5 `write!(&mut Vec<u8>, ...)` calls (io::Write on
`Vec<u8>` never errors), and 3 `Option`-after-guard sites
(`as_mut().expect(...)` post-`ensure_reader()`, `take().expect(...)`
post-`fill_next_block()`, `Byte::from_u64_with_unit(1, MiB)`). No runtime
behavior change.
- Removed the transitional `#![allow(clippy::expect_used)]` quarantine from
`lading_throttle`. All `.expect()` sites in that crate are under
`#[cfg(test)]` or `#[cfg(kani)]`, so the workspace-level
Expand Down
5 changes: 3 additions & 2 deletions lading_payload/src/apache_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl Distribution<StatusCode> for StandardUniform {
StatusCode(
*STATUS_CODES
.choose(rng)
.expect("failed to choose status codes"),
.unwrap_or_else(|| unreachable!("STATUS_CODES is a non-empty const array")),
)
}
}
Expand Down Expand Up @@ -354,7 +354,8 @@ impl crate::Serialize for ApacheCommon {
let member: Member = self.generate(&mut rng)?;
buffer.clear();
// Format into the reusable buffer - write! on Vec<u8> is infallible
write!(&mut buffer, "{member}").expect("formatting to Vec<u8> cannot fail");
write!(&mut buffer, "{member}")
.unwrap_or_else(|_| unreachable!("io::Write on Vec<u8> never errors"));
let line_length = buffer.len() + 1; // add one for the newline
match bytes_remaining.checked_sub(line_length) {
Some(remainder) => {
Expand Down
7 changes: 2 additions & 5 deletions lading_payload/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,10 @@ pub fn default_cache_method() -> CacheMethod {

/// The default block maximum size.
///
/// # Panics
///
/// This function will panic if the byte unit conversion fails, which should never happen
/// with the hardcoded value of 1 MiB.
#[must_use]
pub fn default_maximum_block_size() -> Byte {
Byte::from_u64_with_unit(1, Unit::MiB).expect("catastrophic programming bug")
Byte::from_u64_with_unit(1, Unit::MiB)
.unwrap_or_else(|| unreachable!("1 MiB is always a representable Byte value"))
}

#[derive(Debug)]
Expand Down
18 changes: 13 additions & 5 deletions lading_payload/src/datadog_logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,22 @@ impl<'a> Generator<'a> for DatadogLog {
{
Ok(Member {
message: message(&mut rng, &self.str_pool),
status: STATUSES.choose(rng).expect("failed to generate status"),
status: STATUSES
.choose(rng)
.unwrap_or_else(|| unreachable!("STATUSES is a non-empty const array")),
timestamp: rng.random(),
hostname: HOSTNAMES.choose(rng).expect("failed to generate hostnames"),
service: SERVICES.choose(rng).expect("failed to generate services"),
ddsource: SOURCES.choose(rng).expect("failed to generate sources"),
hostname: HOSTNAMES
.choose(rng)
.unwrap_or_else(|| unreachable!("HOSTNAMES is a non-empty const array")),
service: SERVICES
.choose(rng)
.unwrap_or_else(|| unreachable!("SERVICES is a non-empty const array")),
ddsource: SOURCES
.choose(rng)
.unwrap_or_else(|| unreachable!("SOURCES is a non-empty const array")),
ddtags: TAG_OPTIONS
.choose(rng)
.expect("failed to generate tag options"),
.unwrap_or_else(|| unreachable!("TAG_OPTIONS is a non-empty const array")),
})
}
}
Expand Down
6 changes: 4 additions & 2 deletions lading_payload/src/dogstatsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,8 @@ impl DogStatsD {
let member: Member = self.member_generator.generate(&mut rng)?;
member_buffer.clear();
// Format into the temporary buffer - write! on Vec<u8> is infallible
write!(&mut member_buffer, "{member}").expect("formatting to Vec<u8> cannot fail");
write!(&mut member_buffer, "{member}")
.unwrap_or_else(|_| unreachable!("io::Write on Vec<u8> never errors"));
let line_length = member_buffer.len() + 1; // add one for the newline
if content_buffer.len() + line_length > content_budget {
break;
Expand Down Expand Up @@ -807,7 +808,8 @@ impl DogStatsD {
let member: Member = self.member_generator.generate(&mut rng)?;
buffer.clear();
// Format into the reusable buffer - write! on Vec<u8> is infallible
write!(&mut buffer, "{member}").expect("formatting to Vec<u8> cannot fail");
write!(&mut buffer, "{member}")
.unwrap_or_else(|_| unreachable!("io::Write on Vec<u8> never errors"));
let line_length = buffer.len() + 1; // add one for the newline
match bytes_remaining.checked_sub(line_length) {
Some(remainder) => {
Expand Down
4 changes: 3 additions & 1 deletion lading_payload/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ impl Distribution<Member> for StandardUniform {
where
R: Rng + ?Sized,
{
let max = *SIZES.choose(rng).expect("failed to choose size");
let max = *SIZES
.choose(rng)
.unwrap_or_else(|| unreachable!("SIZES is a non-empty const array"));

// Pre-allocate and fill in one operation rather than iterator-collect.
// Using fill() is faster than sample_iter().take().collect() because
Expand Down
38 changes: 27 additions & 11 deletions lading_payload/src/splunk_hec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,27 @@ impl Distribution<Attrs> for StandardUniform {
R: Rng + ?Sized,
{
Attrs {
system_id: SYSTEM_IDS.choose(rng).expect("failed to choose system ids"),
stage: STAGES.choose(rng).expect("failed to choose stages"),
system_id: SYSTEM_IDS
.choose(rng)
.unwrap_or_else(|| unreachable!("SYSTEM_IDS is a non-empty const array")),
stage: STAGES
.choose(rng)
.unwrap_or_else(|| unreachable!("STAGES is a non-empty const array")),
event_type: EVENT_TYPES
.choose(rng)
.expect("failed to choose event types"),
c2c_service: SERVICES.choose(rng).expect("failed to choose services"),
c2c_partition: PARTITIONS.choose(rng).expect("failed to choose partitions"),
c2c_stage: STAGES.choose(rng).expect("failed to choose stages"),
.unwrap_or_else(|| unreachable!("EVENT_TYPES is a non-empty const array")),
c2c_service: SERVICES
.choose(rng)
.unwrap_or_else(|| unreachable!("SERVICES is a non-empty const array")),
c2c_partition: PARTITIONS
.choose(rng)
.unwrap_or_else(|| unreachable!("PARTITIONS is a non-empty const array")),
c2c_stage: STAGES
.choose(rng)
.unwrap_or_else(|| unreachable!("STAGES is a non-empty const array")),
c2c_container_type: CONTAINER_TYPES
.choose(rng)
.expect("failed to choose container types"),
.unwrap_or_else(|| unreachable!("CONTAINER_TYPES is a non-empty const array")),
aws_account: "verymodelofthemodernmajor",
}
}
Expand All @@ -83,7 +93,9 @@ impl Distribution<Event> for StandardUniform {
{
Event {
timestamp: 1_606_215_269.333_915,
message: MESSAGES.choose(rng).expect("failed to choose messages"),
message: MESSAGES
.choose(rng)
.unwrap_or_else(|| unreachable!("MESSAGES is a non-empty const array")),
attrs: rng.random(),
}
}
Expand All @@ -105,8 +117,12 @@ impl Distribution<Member> for StandardUniform {
Member {
event: rng.random(),
time: rng.random(),
host: SYSTEM_IDS.choose(rng).expect("failed to choose system ids"),
index: PARTITIONS.choose(rng).expect("failed to choose partitions"),
host: SYSTEM_IDS
.choose(rng)
.unwrap_or_else(|| unreachable!("SYSTEM_IDS is a non-empty const array")),
index: PARTITIONS
.choose(rng)
.unwrap_or_else(|| unreachable!("PARTITIONS is a non-empty const array")),
}
}
}
Expand Down Expand Up @@ -166,7 +182,7 @@ impl crate::Serialize for SplunkHec {
timestamp = event.timestamp,
message = event.message
)
.expect("formatting to Vec<u8> cannot fail");
.unwrap_or_else(|_| unreachable!("io::Write on Vec<u8> never errors"));
serde_json::to_writer(&mut buffer, &event.attrs)?;
}
Encoding::Json => serde_json::to_writer(&mut buffer, &member)?,
Expand Down
2 changes: 1 addition & 1 deletion lading_payload/src/static_chunks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl StaticChunks {
let reader = self
.current_reader
.as_mut()
.expect("reader should be present after ensure_reader");
.unwrap_or_else(|| unreachable!("ensure_reader populates current_reader on Ok"));

buf.clear();
let read = reader.read_line(buf)?;
Expand Down
2 changes: 1 addition & 1 deletion lading_payload/src/static_timestamped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ impl crate::Serialize for StaticTimestamped {
let block = self
.next_block
.take()
.expect("fill_next_block guarantees a block");
.unwrap_or_else(|| unreachable!("fill_next_block populates next_block on Ok"));

let mut bytes_written = 0usize;
if block.lines.is_empty() {
Expand Down
10 changes: 7 additions & 3 deletions lading_payload/src/syslog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,12 @@ impl Distribution<Member> for StandardUniform {
.expect("timestamp in valid range");
ts.format(&Rfc3339).expect("failed to format timestamp")
},
hostname: HOSTNAMES.choose(rng).expect("failed to choose hostname"),
app_name: APP_NAMES.choose(rng).expect("failed to choose app name"),
hostname: HOSTNAMES
.choose(rng)
.unwrap_or_else(|| unreachable!("HOSTNAMES is a non-empty const array")),
app_name: APP_NAMES
.choose(rng)
.unwrap_or_else(|| unreachable!("APP_NAMES is a non-empty const array")),
procid: rng.random_range(100..=9999),
msgid: rng.random_range(1..=999),
message: serde_json::to_string(&rng.random::<Message>()).expect("failed to serialize"),
Expand Down Expand Up @@ -115,7 +119,7 @@ impl crate::Serialize for Syslog5424 {
member.msgid,
member.message
)
.expect("formatting to Vec<u8> cannot fail");
.unwrap_or_else(|_| unreachable!("io::Write on Vec<u8> never errors"));

let line_length = buffer.len() + 1; // add one for the newline

Expand Down
Loading