v0.13.0: zero English in library + API hygiene + dead-code sweep
Audit pass against the project docs "no English text in library code" rule.
Found 9 call sites that violated the contract by stuffing English into
io::Error::new(kind, "…") or by abusing Error::DeviceNotFound { path }
as a free-form description field. Each is now a typed Error variant.
New variants and codes: ScsiInterfaceUnavailable (E1004), DeviceLocked
(E1005), IoKitPluginFailed (E1006), UnsupportedPlatform (E2003),
PlatformNotImplemented (E2004), MapfileInvalid (E6011), DiscUrlNotDirect
(E9009).
labels::apply() previously pushed Commentary/Descriptive/Score/IME and
" (Secondary)" English literals into AudioStream.label, leaking into
MKV titles + autorip UI. AudioStream now exposes structured `purpose:
LabelPurpose`, SubtitleStream `qualifier: LabelQualifier`. Callers
translate to localized text. label keeps codec-formatting only.
API hygiene: 11 mux/* modules dropped from `pub` to `pub(crate)` —
their *types* are still re-exported from lib.rs, but the modules were
leaking low-level EBML/TS/network primitives. Stream trait gets a real
rustdoc explaining read-vs-write split. lib.rs grouped re-exports into
documented sections. ScanOptions::with_keydb() removed (one-method-per-
action rule); use struct literal.
Dead-code sweep: removed lookahead.rs (orphan, never declared as mod),
tsreader.rs (TsDemuxReader unused), ebml::{write_int,read_vint,SEEK_*},
ts::{scan_first/last_pts,scan_duration,SCAN_HEAD/TAIL_SIZE,take/set_
remainder}, MkvMuxer codec_private_slots/filled fields and
fill_codec_private method (deferred-codecPrivate path never used since
the v0.10 PES rewrite). cargo clippy --all-targets -D warnings clean.
Tests: new error::tests for variant codes + Display "no English" guard +
io::ErrorKind mapping. 233 lib tests, all green (was 230).
Breaking: ScanOptions::with_keydb removed; mux/* modules pub(crate);
AudioStream and SubtitleStream gained required fields; UnsupportedDrive
{ product_revision: "Renesas not yet implemented" } no longer produced
(use PlatformNotImplemented).
This commit is contained in:
@@ -361,7 +361,9 @@ fn aacs_cross_validation_encrypt_then_decrypt() {
|
||||
plaintext[off] = 0x47;
|
||||
off += 192;
|
||||
}
|
||||
// Fill the rest with a recognisable pattern (prime modulus avoids artefacts)
|
||||
// Fill the rest with a recognisable pattern (prime modulus avoids artefacts).
|
||||
// Index-arithmetic — clearer with a counted loop than an enumerate chain.
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 16..aacs::ALIGNED_UNIT_LEN {
|
||||
if plaintext[i] == 0 {
|
||||
plaintext[i] = (i % 251) as u8;
|
||||
@@ -462,6 +464,7 @@ fn aacs_bus_decrypt_cross_validation() {
|
||||
];
|
||||
|
||||
let mut plaintext = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0..aacs::ALIGNED_UNIT_LEN {
|
||||
plaintext[i] = ((i * 3 + 17) & 0xFF) as u8;
|
||||
}
|
||||
@@ -494,6 +497,7 @@ fn css_roundtrip_with_snapshot() {
|
||||
let mut sector = vec![0x00u8; 2048];
|
||||
sector[0x14] = 0x30;
|
||||
sector[0x54..0x59].copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF, 0x42]);
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0x80..2048 {
|
||||
sector[i] = ((i * 7 + 3) & 0xFF) as u8;
|
||||
}
|
||||
@@ -661,6 +665,7 @@ fn css_recover_title_key_with_exact_plaintext() {
|
||||
sector[0x54..0x59].copy_from_slice(&seed);
|
||||
let pes_header: [u8; 10] = [0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x80, 0x80, 0x05, 0x21];
|
||||
sector[0x80..0x8A].copy_from_slice(&pes_header);
|
||||
#[allow(clippy::needless_range_loop)]
|
||||
for i in 0x8A..2048 {
|
||||
sector[i] = ((i * 13 + 7) & 0xFF) as u8;
|
||||
}
|
||||
|
||||
+9
-3
@@ -133,7 +133,9 @@ fn scan_options_default() {
|
||||
|
||||
#[test]
|
||||
fn scan_options_with_keydb() {
|
||||
let opts = ScanOptions::with_keydb("/tmp/KEYDB.cfg");
|
||||
let opts = ScanOptions {
|
||||
keydb_path: Some(("/tmp/KEYDB.cfg").into()),
|
||||
};
|
||||
assert_eq!(
|
||||
opts.keydb_path.as_ref().unwrap().to_str().unwrap(),
|
||||
"/tmp/KEYDB.cfg"
|
||||
@@ -143,7 +145,9 @@ fn scan_options_with_keydb() {
|
||||
#[test]
|
||||
fn scan_options_with_keydb_pathbuf() {
|
||||
let path = std::path::PathBuf::from("/home/user/.config/aacs/KEYDB.cfg");
|
||||
let opts = ScanOptions::with_keydb(path.clone());
|
||||
let opts = ScanOptions {
|
||||
keydb_path: Some(path.clone()),
|
||||
};
|
||||
assert_eq!(opts.keydb_path.unwrap(), path);
|
||||
}
|
||||
|
||||
@@ -511,7 +515,9 @@ fn resolve_encryption_no_keydb() {
|
||||
build_udf_with_aacs_dir(&mut reader);
|
||||
|
||||
// No keydb configured and no standard keydb on the system
|
||||
let opts = ScanOptions::with_keydb("/nonexistent/path/KEYDB.cfg");
|
||||
let opts = ScanOptions {
|
||||
keydb_path: Some(("/nonexistent/path/KEYDB.cfg").into()),
|
||||
};
|
||||
let disc = Disc::scan_image(&mut reader, 1000, &opts).unwrap();
|
||||
|
||||
// The disc detects encryption but can't resolve keys without a keydb
|
||||
|
||||
@@ -30,6 +30,7 @@ fn sample_disc_title() -> DiscTitle {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "English Atmos".into(),
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
@@ -39,6 +40,7 @@ fn sample_disc_title() -> DiscTitle {
|
||||
language: "fra".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "French".into(),
|
||||
}),
|
||||
Stream::Subtitle(SubtitleStream {
|
||||
@@ -46,6 +48,7 @@ fn sample_disc_title() -> DiscTitle {
|
||||
codec: Codec::Pgs,
|
||||
language: "eng".into(),
|
||||
forced: false,
|
||||
qualifier: libfreemkv::LabelQualifier::None,
|
||||
codec_data: None,
|
||||
}),
|
||||
],
|
||||
@@ -404,6 +407,7 @@ fn meta_codec_roundtrip() {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: String::new(),
|
||||
}));
|
||||
}
|
||||
@@ -413,6 +417,7 @@ fn meta_codec_roundtrip() {
|
||||
codec,
|
||||
language: "eng".into(),
|
||||
forced: false,
|
||||
qualifier: libfreemkv::LabelQualifier::None,
|
||||
codec_data: None,
|
||||
}));
|
||||
}
|
||||
@@ -501,6 +506,7 @@ fn meta_all_stream_types() {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "Primary Audio".into(),
|
||||
}),
|
||||
Stream::Subtitle(SubtitleStream {
|
||||
@@ -508,6 +514,7 @@ fn meta_all_stream_types() {
|
||||
codec: Codec::Pgs,
|
||||
language: "fra".into(),
|
||||
forced: true,
|
||||
qualifier: libfreemkv::LabelQualifier::None,
|
||||
codec_data: None,
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
@@ -517,6 +524,7 @@ fn meta_all_stream_types() {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: true,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "Commentary".into(),
|
||||
}),
|
||||
],
|
||||
@@ -623,6 +631,7 @@ fn mkvstream_roundtrip_bdts() {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "English".into(),
|
||||
})],
|
||||
chapters: Vec::new(),
|
||||
@@ -679,6 +688,7 @@ fn mkvstream_meta_preserves_all_streams() {
|
||||
language: "eng".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "English".into(),
|
||||
}),
|
||||
Stream::Audio(AudioStream {
|
||||
@@ -688,6 +698,7 @@ fn mkvstream_meta_preserves_all_streams() {
|
||||
language: "fra".into(),
|
||||
sample_rate: SampleRate::S48,
|
||||
secondary: false,
|
||||
purpose: libfreemkv::LabelPurpose::Normal,
|
||||
label: "French".into(),
|
||||
}),
|
||||
Stream::Subtitle(SubtitleStream {
|
||||
@@ -695,6 +706,7 @@ fn mkvstream_meta_preserves_all_streams() {
|
||||
codec: Codec::Pgs,
|
||||
language: "eng".into(),
|
||||
forced: false,
|
||||
qualifier: libfreemkv::LabelQualifier::None,
|
||||
codec_data: None,
|
||||
}),
|
||||
Stream::Subtitle(SubtitleStream {
|
||||
@@ -702,6 +714,7 @@ fn mkvstream_meta_preserves_all_streams() {
|
||||
codec: Codec::Pgs,
|
||||
language: "fra".into(),
|
||||
forced: true,
|
||||
qualifier: libfreemkv::LabelQualifier::None,
|
||||
codec_data: None,
|
||||
}),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user