Sweep the pinned toolchain to Rust 1.97
The Windows UI needs current winsafe, whose real minimum is 1.89 (its manifest under-declares 1.87 while it uses NonNull::from_ref). Rather than stop at the minimum, this goes to current stable and fixes what that costs. The counter-intuitive result: 1.97 is CHEAPER than 1.89. libfreemkv had 54 clippy errors at 1.89 and 6 at 1.97, because clippy tightened the noisy collapsible_if lint in between. Stopping at the minimum would have been the most expensive choice available. Roughly 47 lints across the eight repos, the large majority auto-fixed: libfreemkv 6, freemkv-engine 14, bdemu 8, freemkv-keysources 7, autorip 6, freemkv-unlock 3, freemkv-i18n 3. The hand-fixed ones are a descending sort to sort_by_key(Reverse), four manual checked-division sites, a loop counter replaced by enumerate, and a loop whose first let-else became a while-let. Worth recording for whoever bumps next: clippy is MSRV-AWARE. Those 54 lints only appear once the crate DECLARES 1.89 or later, because let-chains become available. A bare `cargo +1.89 clippy` against a manifest still pinned at 1.87 reports clean and is meaningless — gate with the real precommit script, which is also the only thing that covers build scripts. The pin still sits below the Mac default, so it keeps doing its job: catching lint drift locally before CI sees it.
This commit is contained in:
+12
-12
@@ -100,10 +100,10 @@ pub fn parse(reader: &mut dyn SectorSource, udf: &UdfFs) -> Option<DiscMetadata>
|
||||
// Disc-set position is disc-global; first one we successfully
|
||||
// read wins. (All bdmt_*.xml on a given disc carry the same
|
||||
// value in practice.)
|
||||
if out.disc_number.is_none() {
|
||||
if let Some(ds) = disc_set {
|
||||
out.disc_number = Some(ds);
|
||||
}
|
||||
if out.disc_number.is_none()
|
||||
&& let Some(ds) = disc_set
|
||||
{
|
||||
out.disc_number = Some(ds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,20 +184,20 @@ fn extract_title(xml_text: &str) -> Option<String> {
|
||||
// xml::text already trims its result, so an empty string after
|
||||
// extraction means a genuinely empty element.
|
||||
for tag in ["name", "title"] {
|
||||
if let Some(s) = xml::text(xml_text, tag) {
|
||||
if !s.is_empty() {
|
||||
return Some(s);
|
||||
}
|
||||
if let Some(s) = xml::text(xml_text, tag)
|
||||
&& !s.is_empty()
|
||||
{
|
||||
return Some(s);
|
||||
}
|
||||
}
|
||||
// tableOfContents/titleName: search inside the toc block so we
|
||||
// don't accidentally pick a stray <titleName> from elsewhere.
|
||||
if let Some((s, e)) = xml::find_element(xml_text, "tableOfContents", 0) {
|
||||
let block = &xml_text[s..e];
|
||||
if let Some(t) = xml::text(block, "titleName") {
|
||||
if !t.is_empty() {
|
||||
return Some(t);
|
||||
}
|
||||
if let Some(t) = xml::text(block, "titleName")
|
||||
&& !t.is_empty()
|
||||
{
|
||||
return Some(t);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
+11
-12
@@ -36,10 +36,10 @@ pub fn parse(reader: &mut dyn SectorSource, udf: &UdfFs) -> Option<ParseResult>
|
||||
|
||||
// Stream number mapping from playbackconfig.xml
|
||||
let mut stream_map: HashMap<String, u16> = HashMap::new();
|
||||
if let Some(pc_data) = super::read_jar_file(reader, udf, "playbackconfig.xml") {
|
||||
if let Ok(pc_text) = std::str::from_utf8(&pc_data) {
|
||||
parse_playback_config(pc_text, &mut stream_map);
|
||||
}
|
||||
if let Some(pc_data) = super::read_jar_file(reader, udf, "playbackconfig.xml")
|
||||
&& let Ok(pc_text) = std::str::from_utf8(&pc_data)
|
||||
{
|
||||
parse_playback_config(pc_text, &mut stream_map);
|
||||
}
|
||||
|
||||
let stream_nums = assign_stream_numbers(&stream_infos, &stream_map);
|
||||
@@ -189,14 +189,13 @@ fn parse_playback_config(text: &str, map: &mut HashMap<String, u16>) {
|
||||
if let (Some(stream_id_str), Some(info_id)) = (
|
||||
xml::text(block, "StreamID"),
|
||||
xml::text(block, "StreamInfo_ID"),
|
||||
) {
|
||||
if let Ok(stream_num) = stream_id_str.parse::<u16>() {
|
||||
// Stream numbers are 1-based per the apply_labels
|
||||
// contract; a mapped 0 is unmatchable and silently
|
||||
// drops the label. Skip it rather than store it.
|
||||
if stream_num != 0 {
|
||||
map.insert(info_id, stream_num);
|
||||
}
|
||||
) && let Ok(stream_num) = stream_id_str.parse::<u16>()
|
||||
{
|
||||
// Stream numbers are 1-based per the apply_labels
|
||||
// contract; a mapped 0 is unmatchable and silently
|
||||
// drops the label. Skip it rather than store it.
|
||||
if stream_num != 0 {
|
||||
map.insert(info_id, stream_num);
|
||||
}
|
||||
}
|
||||
from = end;
|
||||
|
||||
+3
-3
@@ -50,10 +50,10 @@ fn merge(ls: Vec<StreamLabel>, mb: Vec<StreamLabel>) -> Vec<StreamLabel> {
|
||||
if let Some(mb_match) = mb
|
||||
.iter()
|
||||
.find(|m| m.stream_type == label.stream_type && m.stream_number == label.stream_number)
|
||||
&& label.name.is_empty()
|
||||
&& !mb_match.name.is_empty()
|
||||
{
|
||||
if label.name.is_empty() && !mb_match.name.is_empty() {
|
||||
label.name = mb_match.name.clone();
|
||||
}
|
||||
label.name = mb_match.name.clone();
|
||||
}
|
||||
}
|
||||
// Append any menu_base-only stream (present in mb but not in ls by
|
||||
|
||||
+7
-7
@@ -114,13 +114,13 @@ fn collect_textfield(
|
||||
if let Ok(n) = rest.parse::<u16>() {
|
||||
audios.insert(n, label.to_string());
|
||||
}
|
||||
} else if let Some(rest) = kind_n.strip_prefix("Subtitle") {
|
||||
if let Ok(n) = rest.parse::<u16>() {
|
||||
// Subtitle0 is conventionally the "None / Off" disable
|
||||
// button, not an actual subtitle stream.
|
||||
if n > 0 {
|
||||
subs.insert(n, label.to_string());
|
||||
}
|
||||
} else if let Some(rest) = kind_n.strip_prefix("Subtitle")
|
||||
&& let Ok(n) = rest.parse::<u16>()
|
||||
{
|
||||
// Subtitle0 is conventionally the "None / Off" disable
|
||||
// button, not an actual subtitle stream.
|
||||
if n > 0 {
|
||||
subs.insert(n, label.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,14 +596,13 @@ impl<'a> BindingDecoder<'a> {
|
||||
// Underneath the args: the object the constructor
|
||||
// operates on. For our pattern it's NewObj(X).
|
||||
let receiver = self.stack.pop().unwrap_or(StackVal::Unknown);
|
||||
if let StackVal::NewObj(name) = receiver {
|
||||
if name == member.class_name {
|
||||
if let StackVal::NewObj(name) = receiver
|
||||
&& name == member.class_name {
|
||||
self.constructions.push(Construction {
|
||||
binding_type: name,
|
||||
args,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
// invokevirtual / invokestatic / invokeinterface — pop
|
||||
// args per descriptor, push a return placeholder unless
|
||||
|
||||
+4
-4
@@ -574,10 +574,10 @@ fn extract(reader: &mut dyn SectorSource, udf: &UdfFs) -> Vec<StreamLabel> {
|
||||
// so the user sees every track even when only the "interesting"
|
||||
// ones have editorial names. Skips the merge when mpls_universal
|
||||
// was itself the chosen parser (its labels ARE the labels).
|
||||
if name != "mpls_universal" {
|
||||
if let Some(mpls_result) = mpls_universal::parse(reader, udf) {
|
||||
fill_gaps_from_mpls(&mut labels, &mpls_result.labels);
|
||||
}
|
||||
if name != "mpls_universal"
|
||||
&& let Some(mpls_result) = mpls_universal::parse(reader, udf)
|
||||
{
|
||||
fill_gaps_from_mpls(&mut labels, &mpls_result.labels);
|
||||
}
|
||||
|
||||
// CLPI orphan streams: PIDs in /BDMV/CLIPINF/*.clpi ProgramInfo
|
||||
|
||||
@@ -142,10 +142,10 @@ fn find_feature_playlist(text: &str) -> Option<String> {
|
||||
let element = &text[start..end];
|
||||
|
||||
// Prefer name="Feature" explicitly.
|
||||
if let Some(name) = xml::attr(element, "name") {
|
||||
if name.eq_ignore_ascii_case("Feature") {
|
||||
return Some(element.to_string());
|
||||
}
|
||||
if let Some(name) = xml::attr(element, "name")
|
||||
&& name.eq_ignore_ascii_case("Feature")
|
||||
{
|
||||
return Some(element.to_string());
|
||||
}
|
||||
|
||||
// Otherwise pick the one with the most audio streams. Count only
|
||||
|
||||
@@ -41,10 +41,10 @@ pub fn parse(_reader: &mut dyn SectorSource, udf: &UdfFs) -> Option<ParseResult>
|
||||
fn labels_from_filenames(names: &[String]) -> Vec<StreamLabel> {
|
||||
let mut seen: Vec<&'static str> = Vec::new();
|
||||
for name in names {
|
||||
if let Some(code) = filename_lang(name) {
|
||||
if !seen.contains(&code) {
|
||||
seen.push(code);
|
||||
}
|
||||
if let Some(code) = filename_lang(name)
|
||||
&& !seen.contains(&code)
|
||||
{
|
||||
seen.push(code);
|
||||
}
|
||||
}
|
||||
seen.into_iter()
|
||||
|
||||
Reference in New Issue
Block a user