Doc comments, format string inlining, long literal separators
- Doc comments on DriveSession, find_drives, all Error variants, Result type - 24 format! strings inlined (clippy pedantic) - 25 long hex literals with separators (0xFFFFFFFF → 0xFFFF_FFFF) - README install example updated to 0.8
This commit is contained in:
+1
-1
@@ -59,7 +59,7 @@ impl Disc {
|
|||||||
2 => "stereo".to_string(),
|
2 => "stereo".to_string(),
|
||||||
6 => "5.1".to_string(),
|
6 => "5.1".to_string(),
|
||||||
8 => "7.1".to_string(),
|
8 => "7.1".to_string(),
|
||||||
n => format!("{}ch", n),
|
n => format!("{n}ch"),
|
||||||
};
|
};
|
||||||
let sample_rate = match a.sample_rate {
|
let sample_rate = match a.sample_rate {
|
||||||
48000 => "48kHz".to_string(),
|
48000 => "48kHz".to_string(),
|
||||||
|
|||||||
+4
-4
@@ -333,7 +333,7 @@ impl DiscTitle {
|
|||||||
pub fn duration_display(&self) -> String {
|
pub fn duration_display(&self) -> String {
|
||||||
let hrs = (self.duration_secs / 3600.0) as u32;
|
let hrs = (self.duration_secs / 3600.0) as u32;
|
||||||
let mins = ((self.duration_secs % 3600.0) / 60.0) as u32;
|
let mins = ((self.duration_secs % 3600.0) / 60.0) as u32;
|
||||||
format!("{}h {:02}m", hrs, mins)
|
format!("{hrs}h {mins:02}m")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size in GB
|
/// Size in GB
|
||||||
@@ -761,7 +761,7 @@ pub(crate) fn detect_max_batch_sectors(device_path: &str) -> u16 {
|
|||||||
|
|
||||||
// For sg devices, find the corresponding block device name
|
// For sg devices, find the corresponding block device name
|
||||||
let block_name = if dev_name.starts_with("sg") {
|
let block_name = if dev_name.starts_with("sg") {
|
||||||
let block_dir = format!("/sys/class/scsi_generic/{}/device/block", dev_name);
|
let block_dir = format!("/sys/class/scsi_generic/{dev_name}/device/block");
|
||||||
std::fs::read_dir(&block_dir)
|
std::fs::read_dir(&block_dir)
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|mut entries| entries.next())
|
.and_then(|mut entries| entries.next())
|
||||||
@@ -772,7 +772,7 @@ pub(crate) fn detect_max_batch_sectors(device_path: &str) -> u16 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(bname) = block_name {
|
if let Some(bname) = block_name {
|
||||||
let sysfs_path = format!("/sys/block/{}/queue/max_hw_sectors_kb", bname);
|
let sysfs_path = format!("/sys/block/{bname}/queue/max_hw_sectors_kb");
|
||||||
if let Ok(content) = std::fs::read_to_string(&sysfs_path) {
|
if let Ok(content) = std::fs::read_to_string(&sysfs_path) {
|
||||||
if let Ok(kb) = content.trim().parse::<u32>() {
|
if let Ok(kb) = content.trim().parse::<u32>() {
|
||||||
// Convert KB to sectors (1 sector = 2 KB = 2048 bytes)
|
// Convert KB to sectors (1 sector = 2 KB = 2048 bytes)
|
||||||
@@ -1045,7 +1045,7 @@ fn format_channels(audio_format: u8) -> String {
|
|||||||
3 => "stereo".into(),
|
3 => "stereo".into(),
|
||||||
6 => "5.1".into(),
|
6 => "5.1".into(),
|
||||||
12 => "7.1".into(),
|
12 => "7.1".into(),
|
||||||
_ if audio_format > 0 => format!("{}ch", audio_format),
|
_ if audio_format > 0 => format!("{audio_format}ch"),
|
||||||
_ => String::new(),
|
_ => String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -6,7 +6,7 @@ use crate::identity::DriveId;
|
|||||||
pub fn find_drives() -> Vec<(String, DriveId)> {
|
pub fn find_drives() -> Vec<(String, DriveId)> {
|
||||||
let mut drives = Vec::new();
|
let mut drives = Vec::new();
|
||||||
for i in 0..16 {
|
for i in 0..16 {
|
||||||
let path = format!("/dev/sg{}", i);
|
let path = format!("/dev/sg{i}");
|
||||||
if !std::path::Path::new(&path).exists() {
|
if !std::path::Path::new(&path).exists() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -40,8 +40,7 @@ pub fn resolve_device(path: &str) -> Result<(String, Option<String>)> {
|
|||||||
&& sg_id.serial_number == sr_id.serial_number
|
&& sg_id.serial_number == sr_id.serial_number
|
||||||
{
|
{
|
||||||
let warning = format!(
|
let warning = format!(
|
||||||
"{} is a block device (sr) — using {} (sg) for raw access",
|
"{path} is a block device (sr) — using {sg_path} (sg) for raw access"
|
||||||
path, sg_path
|
|
||||||
);
|
);
|
||||||
return Ok((sg_path, Some(warning)));
|
return Ok((sg_path, Some(warning)));
|
||||||
}
|
}
|
||||||
@@ -49,8 +48,7 @@ pub fn resolve_device(path: &str) -> Result<(String, Option<String>)> {
|
|||||||
return Ok((
|
return Ok((
|
||||||
path.to_string(),
|
path.to_string(),
|
||||||
Some(format!(
|
Some(format!(
|
||||||
"{} is a block device (sr) — no matching sg device found",
|
"{path} is a block device (sr) — no matching sg device found"
|
||||||
path
|
|
||||||
)),
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -265,7 +265,7 @@ fn parse_vts(
|
|||||||
vts_number: u8,
|
vts_number: u8,
|
||||||
titles_info: &[(u16, u8)],
|
titles_info: &[(u16, u8)],
|
||||||
) -> Result<DvdTitleSet> {
|
) -> Result<DvdTitleSet> {
|
||||||
let path = format!("/VIDEO_TS/VTS_{:02}_0.IFO", vts_number);
|
let path = format!("/VIDEO_TS/VTS_{vts_number:02}_0.IFO");
|
||||||
let vts_data = udf.read_file(reader, &path)?;
|
let vts_data = udf.read_file(reader, &path)?;
|
||||||
|
|
||||||
// Validate VTS magic
|
// Validate VTS magic
|
||||||
|
|||||||
+2
-3
@@ -83,7 +83,7 @@ fn http_get(url: &str) -> Result<Vec<u8>> {
|
|||||||
let (mut host, mut port, mut path) = parse_url(url)?;
|
let (mut host, mut port, mut path) = parse_url(url)?;
|
||||||
|
|
||||||
for _ in 0..5 {
|
for _ in 0..5 {
|
||||||
let addr = format!("{}:{}", host, port);
|
let addr = format!("{host}:{port}");
|
||||||
let mut stream =
|
let mut stream =
|
||||||
TcpStream::connect(&addr).map_err(|_| Error::KeydbConnect { host: host.clone() })?;
|
TcpStream::connect(&addr).map_err(|_| Error::KeydbConnect { host: host.clone() })?;
|
||||||
stream
|
stream
|
||||||
@@ -91,8 +91,7 @@ fn http_get(url: &str) -> Result<Vec<u8>> {
|
|||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
let request = format!(
|
let request = format!(
|
||||||
"GET {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nAccept-Encoding: identity\r\n\r\n",
|
"GET {path} HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\nAccept-Encoding: identity\r\n\r\n"
|
||||||
path, host
|
|
||||||
);
|
);
|
||||||
stream
|
stream
|
||||||
.write_all(request.as_bytes())
|
.write_all(request.as_bytes())
|
||||||
|
|||||||
@@ -174,8 +174,8 @@ fn parse_playback_config(xml: &str, map: &mut HashMap<String, u16>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn extract_tag(xml: &str, tag: &str) -> Option<String> {
|
fn extract_tag(xml: &str, tag: &str) -> Option<String> {
|
||||||
let open = format!("<{}>", tag);
|
let open = format!("<{tag}>");
|
||||||
let close = format!("</{}>", tag);
|
let close = format!("</{tag}>");
|
||||||
let start = xml.find(&open)? + open.len();
|
let start = xml.find(&open)? + open.len();
|
||||||
let end = xml[start..].find(&close)? + start;
|
let end = xml[start..].find(&close)? + start;
|
||||||
Some(xml[start..end].trim().to_string())
|
Some(xml[start..end].trim().to_string())
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ fn find_feature_playlist(xml: &str) -> Option<String> {
|
|||||||
|
|
||||||
/// Extract an XML attribute value from an element string.
|
/// Extract an XML attribute value from an element string.
|
||||||
fn extract_attr(element: &str, name: &str) -> Option<String> {
|
fn extract_attr(element: &str, name: &str) -> Option<String> {
|
||||||
let needle = format!("{}=\"", name);
|
let needle = format!("{name}=\"");
|
||||||
let start = element.find(&needle)? + needle.len();
|
let start = element.find(&needle)? + needle.len();
|
||||||
let end = element[start..].find('"')? + start;
|
let end = element[start..].find('"')? + start;
|
||||||
Some(element[start..end].to_string())
|
Some(element[start..end].to_string())
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ pub fn format_palette(palette: &[[u8; 4]]) -> Vec<u8> {
|
|||||||
let mut parts: Vec<String> = Vec::with_capacity(palette.len());
|
let mut parts: Vec<String> = Vec::with_capacity(palette.len());
|
||||||
for color in palette {
|
for color in palette {
|
||||||
let [r, g, b] = ycbcr_to_rgb(color);
|
let [r, g, b] = ycbcr_to_rgb(color);
|
||||||
parts.push(format!("{:02x}{:02x}{:02x}", r, g, b));
|
parts.push(format!("{r:02x}{g:02x}{b:02x}"));
|
||||||
}
|
}
|
||||||
let line = format!("palette: {}\n", parts.join(", "));
|
let line = format!("palette: {}\n", parts.join(", "));
|
||||||
line.into_bytes()
|
line.into_bytes()
|
||||||
|
|||||||
+3
-3
@@ -356,7 +356,7 @@ pub const SEEK_POSITION: u32 = 0x53AC;
|
|||||||
|
|
||||||
// Segment Info
|
// Segment Info
|
||||||
pub const INFO: u32 = 0x1549_A966;
|
pub const INFO: u32 = 0x1549_A966;
|
||||||
pub const TIMESTAMP_SCALE: u32 = 0x2AD7B1;
|
pub const TIMESTAMP_SCALE: u32 = 0x2A_D7B1;
|
||||||
pub const DURATION: u32 = 0x4489;
|
pub const DURATION: u32 = 0x4489;
|
||||||
pub const MUXING_APP: u32 = 0x4D80;
|
pub const MUXING_APP: u32 = 0x4D80;
|
||||||
pub const WRITING_APP: u32 = 0x5741;
|
pub const WRITING_APP: u32 = 0x5741;
|
||||||
@@ -371,11 +371,11 @@ pub const TRACK_TYPE: u32 = 0x83;
|
|||||||
pub const FLAG_LACING: u32 = 0x9C;
|
pub const FLAG_LACING: u32 = 0x9C;
|
||||||
pub const FLAG_DEFAULT: u32 = 0x88;
|
pub const FLAG_DEFAULT: u32 = 0x88;
|
||||||
pub const FLAG_FORCED: u32 = 0x55AA;
|
pub const FLAG_FORCED: u32 = 0x55AA;
|
||||||
pub const LANGUAGE: u32 = 0x22B59C;
|
pub const LANGUAGE: u32 = 0x22_B59C;
|
||||||
pub const CODEC_ID: u32 = 0x86;
|
pub const CODEC_ID: u32 = 0x86;
|
||||||
pub const CODEC_PRIVATE: u32 = 0x63A2;
|
pub const CODEC_PRIVATE: u32 = 0x63A2;
|
||||||
pub const TRACK_NAME: u32 = 0x536E;
|
pub const TRACK_NAME: u32 = 0x536E;
|
||||||
pub const DEFAULT_DURATION: u32 = 0x23E383;
|
pub const DEFAULT_DURATION: u32 = 0x23_E383;
|
||||||
|
|
||||||
// Video
|
// Video
|
||||||
pub const VIDEO: u32 = 0xE0;
|
pub const VIDEO: u32 = 0xE0;
|
||||||
|
|||||||
+2
-2
@@ -30,7 +30,7 @@ pub struct IsoSectorReader {
|
|||||||
impl IsoSectorReader {
|
impl IsoSectorReader {
|
||||||
pub fn open(path: &str) -> io::Result<Self> {
|
pub fn open(path: &str) -> io::Result<Self> {
|
||||||
let file = File::open(Path::new(path))
|
let file = File::open(Path::new(path))
|
||||||
.map_err(|e| io::Error::new(e.kind(), format!("iso://{}: {}", path, e)))?;
|
.map_err(|e| io::Error::new(e.kind(), format!("iso://{path}: {e}")))?;
|
||||||
let size = file.metadata()?.len();
|
let size = file.metadata()?.len();
|
||||||
let capacity = (size / SECTOR_SIZE) as u32;
|
let capacity = (size / SECTOR_SIZE) as u32;
|
||||||
Ok(Self { file, capacity })
|
Ok(Self { file, capacity })
|
||||||
@@ -123,7 +123,7 @@ impl IsoStream {
|
|||||||
/// Create an ISO file for writing.
|
/// Create an ISO file for writing.
|
||||||
pub fn create(path: &str) -> io::Result<Self> {
|
pub fn create(path: &str) -> io::Result<Self> {
|
||||||
let file = File::create(Path::new(path))
|
let file = File::create(Path::new(path))
|
||||||
.map_err(|e| io::Error::new(e.kind(), format!("iso://{}: {}", path, e)))?;
|
.map_err(|e| io::Error::new(e.kind(), format!("iso://{path}: {e}")))?;
|
||||||
let buf_writer = io::BufWriter::with_capacity(4 * 1024 * 1024, file);
|
let buf_writer = io::BufWriter::with_capacity(4 * 1024 * 1024, file);
|
||||||
let iso_writer = IsoWriter::new(buf_writer, "FREEMKV", "00001.m2ts");
|
let iso_writer = IsoWriter::new(buf_writer, "FREEMKV", "00001.m2ts");
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ impl<W: Write + Seek> IsoWriter<W> {
|
|||||||
// Partition starting location at offset 188
|
// Partition starting location at offset 188
|
||||||
pd[188..192].copy_from_slice(&PARTITION_START.to_le_bytes());
|
pd[188..192].copy_from_slice(&PARTITION_START.to_le_bytes());
|
||||||
// Partition length (large enough for everything)
|
// Partition length (large enough for everything)
|
||||||
let part_len: u32 = 0xFFFFFFFF;
|
let part_len: u32 = 0xFFFF_FFFF;
|
||||||
pd[192..196].copy_from_slice(&part_len.to_le_bytes());
|
pd[192..196].copy_from_slice(&part_len.to_le_bytes());
|
||||||
self.writer.write_all(&pd)?;
|
self.writer.write_all(&pd)?;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -183,7 +183,7 @@ impl<W: Write + Seek> MkvMuxer<W> {
|
|||||||
for (i, track) in tracks.iter().enumerate() {
|
for (i, track) in tracks.iter().enumerate() {
|
||||||
let entry_pos = ebml::start_master(&mut writer, ebml::TRACK_ENTRY)?;
|
let entry_pos = ebml::start_master(&mut writer, ebml::TRACK_ENTRY)?;
|
||||||
ebml::write_uint(&mut writer, ebml::TRACK_NUMBER, (i + 1) as u64)?;
|
ebml::write_uint(&mut writer, ebml::TRACK_NUMBER, (i + 1) as u64)?;
|
||||||
ebml::write_uint(&mut writer, ebml::TRACK_UID, (i + 1) as u64 | 0x1000000)?;
|
ebml::write_uint(&mut writer, ebml::TRACK_UID, (i + 1) as u64 | 0x100_0000)?;
|
||||||
ebml::write_uint(&mut writer, ebml::TRACK_TYPE, track.track_type)?;
|
ebml::write_uint(&mut writer, ebml::TRACK_TYPE, track.track_type)?;
|
||||||
ebml::write_uint(&mut writer, ebml::FLAG_LACING, 0)?;
|
ebml::write_uint(&mut writer, ebml::FLAG_LACING, 0)?;
|
||||||
ebml::write_string(&mut writer, ebml::CODEC_ID, track.codec_id)?;
|
ebml::write_string(&mut writer, ebml::CODEC_ID, track.codec_id)?;
|
||||||
@@ -432,7 +432,7 @@ fn parse_resolution(s: &str) -> (u32, u32) {
|
|||||||
|
|
||||||
fn parse_sample_rate(s: &str) -> f64 {
|
fn parse_sample_rate(s: &str) -> f64 {
|
||||||
if s.contains("192") {
|
if s.contains("192") {
|
||||||
192000.0
|
192_000.0
|
||||||
} else if s.contains("96") {
|
} else if s.contains("96") {
|
||||||
96000.0
|
96000.0
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ fn parse_track(r: &mut (impl Read + Seek), size: u64) -> io::Result<Option<crate
|
|||||||
"S_VOBSUB" => Codec::DvdSub,
|
"S_VOBSUB" => Codec::DvdSub,
|
||||||
_ => Codec::Unknown(0),
|
_ => Codec::Unknown(0),
|
||||||
};
|
};
|
||||||
let res = format!("{}p", ph);
|
let res = format!("{ph}p");
|
||||||
let chs: String = match ch {
|
let chs: String = match ch {
|
||||||
8 => "7.1",
|
8 => "7.1",
|
||||||
6 => "5.1",
|
6 => "5.1",
|
||||||
|
|||||||
+3
-6
@@ -104,8 +104,7 @@ fn validate_file_path(path: &str, scheme: &str) -> io::Result<()> {
|
|||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
format!(
|
format!(
|
||||||
"{}:// requires a file path (e.g. {}://movie.{})",
|
"{scheme}:// requires a file path (e.g. {scheme}://movie.{scheme})"
|
||||||
scheme, scheme, scheme
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -114,8 +113,7 @@ fn validate_file_path(path: &str, scheme: &str) -> io::Result<()> {
|
|||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
format!(
|
format!(
|
||||||
"{}://{} is not a valid file path — must include a filename",
|
"{scheme}://{path} is not a valid file path — must include a filename"
|
||||||
scheme, path
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -134,8 +132,7 @@ fn validate_network_addr(addr: &str) -> io::Result<()> {
|
|||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
io::ErrorKind::InvalidInput,
|
io::ErrorKind::InvalidInput,
|
||||||
format!(
|
format!(
|
||||||
"network://{} missing port — use network://{}:PORT",
|
"network://{addr} missing port — use network://{addr}:PORT"
|
||||||
addr, addr
|
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -288,7 +288,7 @@ impl UdfFs {
|
|||||||
|
|
||||||
let raw_len = u32::from_le_bytes([icb[off], icb[off + 1], icb[off + 2], icb[off + 3]]);
|
let raw_len = u32::from_le_bytes([icb[off], icb[off + 1], icb[off + 2], icb[off + 3]]);
|
||||||
let extent_type = raw_len >> 30;
|
let extent_type = raw_len >> 30;
|
||||||
let data_len = raw_len & 0x3FFFFFFF;
|
let data_len = raw_len & 0x3FFF_FFFF;
|
||||||
let data_lba =
|
let data_lba =
|
||||||
u32::from_le_bytes([icb[off + 4], icb[off + 5], icb[off + 6], icb[off + 7]]);
|
u32::from_le_bytes([icb[off + 4], icb[off + 5], icb[off + 6], icb[off + 7]]);
|
||||||
|
|
||||||
@@ -455,7 +455,7 @@ pub fn read_filesystem(reader: &mut dyn SectorReader) -> Result<UdfFs> {
|
|||||||
meta_icb[ad_off + 1],
|
meta_icb[ad_off + 1],
|
||||||
meta_icb[ad_off + 2],
|
meta_icb[ad_off + 2],
|
||||||
meta_icb[ad_off + 3],
|
meta_icb[ad_off + 3],
|
||||||
]) & 0x3FFFFFFF;
|
]) & 0x3FFF_FFFF;
|
||||||
metadata_size_bytes = ad_len;
|
metadata_size_bytes = ad_len;
|
||||||
let ad_pos = u32::from_le_bytes([
|
let ad_pos = u32::from_le_bytes([
|
||||||
meta_icb[ad_off + 4],
|
meta_icb[ad_off + 4],
|
||||||
@@ -543,7 +543,7 @@ fn read_directory(
|
|||||||
icb[ad_off + 1],
|
icb[ad_off + 1],
|
||||||
icb[ad_off + 2],
|
icb[ad_off + 2],
|
||||||
icb[ad_off + 3],
|
icb[ad_off + 3],
|
||||||
]) & 0x3FFFFFFF;
|
]) & 0x3FFF_FFFF;
|
||||||
let pos = u32::from_le_bytes([
|
let pos = u32::from_le_bytes([
|
||||||
icb[ad_off + 4],
|
icb[ad_off + 4],
|
||||||
icb[ad_off + 5],
|
icb[ad_off + 5],
|
||||||
@@ -565,7 +565,7 @@ fn read_directory(
|
|||||||
icb[ad_off + 1],
|
icb[ad_off + 1],
|
||||||
icb[ad_off + 2],
|
icb[ad_off + 2],
|
||||||
icb[ad_off + 3],
|
icb[ad_off + 3],
|
||||||
]) & 0x3FFFFFFF;
|
]) & 0x3FFF_FFFF;
|
||||||
let pos = u32::from_le_bytes([
|
let pos = u32::from_le_bytes([
|
||||||
icb[ad_off + 4],
|
icb[ad_off + 4],
|
||||||
icb[ad_off + 5],
|
icb[ad_off + 5],
|
||||||
|
|||||||
Reference in New Issue
Block a user