diff --git a/server/base/clock.rs b/server/base/clock.rs index d4450a1..52d64a4 100644 --- a/server/base/clock.rs +++ b/server/base/clock.rs @@ -5,7 +5,6 @@ //! Clock interface and implementations for testability. use failure::Error; -use libc; use log::warn; use parking_lot::Mutex; use std::mem; @@ -136,7 +135,7 @@ struct SimulatedClocksInner { impl SimulatedClocks { pub fn new(boot: Timespec) -> Self { SimulatedClocks(Arc::new(SimulatedClocksInner { - boot: boot, + boot, uptime: Mutex::new(Duration::seconds(0)), })) } @@ -163,7 +162,7 @@ impl Clocks for SimulatedClocks { timeout: StdDuration, ) -> Result { let r = rcv.recv_timeout(StdDuration::new(0, 0)); - if let Err(_) = r { + if r.is_err() { self.sleep(Duration::from_std(timeout).unwrap()); } r diff --git a/server/base/strutil.rs b/server/base/strutil.rs index c593a94..fe06e79 100644 --- a/server/base/strutil.rs +++ b/server/base/strutil.rs @@ -27,7 +27,7 @@ pub fn encode_size(mut raw: i64) -> String { raw &= (1i64 << n) - 1; } } - if raw > 0 || encoded.len() == 0 { + if raw > 0 || encoded.is_empty() { write!(&mut encoded, "{}", raw).unwrap(); } else { encoded.pop(); // remove trailing space. @@ -39,7 +39,7 @@ fn decode_sizepart(input: &str) -> IResult<&str, i64> { map( tuple(( map_res(take_while1(|c: char| c.is_ascii_digit()), |input: &str| { - i64::from_str_radix(input, 10) + input.parse::() }), opt(alt(( nom::combinator::value(1 << 40, tag("T")), diff --git a/server/base/time.rs b/server/base/time.rs index 61372ec..3f98328 100644 --- a/server/base/time.rs +++ b/server/base/time.rs @@ -13,7 +13,6 @@ use serde::{Deserialize, Serialize}; use std::fmt; use std::ops; use std::str::FromStr; -use time; type IResult<'a, I, O> = nom::IResult>; @@ -27,7 +26,7 @@ pub struct Time(pub i64); fn fixed_len_num<'a>(len: usize) -> impl FnMut(&'a str) -> IResult<&'a str, i32> { map_res( take_while_m_n(len, len, |c: char| c.is_ascii_digit()), - |input: &str| i32::from_str_radix(input, 10), + |input: &str| input.parse::(), ) } @@ -96,9 +95,8 @@ impl Time { /// local time zone. pub fn parse(input: &str) -> Result { // First try parsing as 90,000ths of a second since epoch. - match i64::from_str(input) { - Ok(i) => return Ok(Time(i)), - Err(_) => {} + if let Ok(i) = i64::from_str(input) { + return Ok(Time(i)); } // If that failed, parse as a time string or bust. @@ -113,7 +111,7 @@ impl Time { format_err!("{}", nom::error::convert_error(input, e)) } })?; - if remaining != "" { + if !remaining.is_empty() { bail!("unexpected suffix {:?} following time string", remaining); } let (tm_hour, tm_min, tm_sec, subsec) = opt_time.unwrap_or((0, 0, 0, 0)); @@ -210,7 +208,7 @@ impl fmt::Display for Time { write!( f, "{}:{:05}{}{:02}:{:02}", - tm.strftime("%FT%T").or_else(|_| Err(fmt::Error))?, + tm.strftime("%FT%T").map_err(|_| fmt::Error)?, self.0 % TIME_UNITS_PER_SEC, if tm.tm_utcoff > 0 { '+' } else { '-' }, zone_minutes / 60, diff --git a/server/db/auth.rs b/server/db/auth.rs index b22668c..d92b0f6 100644 --- a/server/db/auth.rs +++ b/server/db/auth.rs @@ -9,7 +9,6 @@ use base::{bail_t, format_err_t, strutil, ErrorKind, ResultExt}; use failure::{bail, format_err, Error}; use fnv::FnvHashMap; use lazy_static::lazy_static; -use libpasta; use log::info; use parking_lot::Mutex; use protobuf::Message; @@ -239,12 +238,8 @@ impl Session { pub struct RawSessionId([u8; 48]); impl RawSessionId { - pub fn new() -> Self { - RawSessionId([0u8; 48]) - } - pub fn decode_base64(input: &[u8]) -> Result { - let mut s = RawSessionId::new(); + let mut s = RawSessionId([0u8; 48]); let l = ::base64::decode_config_slice(input, ::base64::STANDARD_NO_PAD, &mut s.0[..])?; if l != 48 { bail!("session id must be 48 bytes"); @@ -625,7 +620,7 @@ impl State { sessions: &'s mut FnvHashMap, permissions: Permissions, ) -> Result<(RawSessionId, &'s Session), Error> { - let mut session_id = RawSessionId::new(); + let mut session_id = RawSessionId([0u8; 48]); rand.fill(&mut session_id.0).unwrap(); let mut seed = [0u8; 32]; rand.fill(&mut seed).unwrap(); @@ -793,7 +788,7 @@ impl State { ":id": &id, })?; } - for (_, s) in &self.sessions { + for s in self.sessions.values() { if !s.dirty { continue; } @@ -813,10 +808,10 @@ impl State { /// /// See notes there. pub fn post_flush(&mut self) { - for (_, u) in &mut self.users_by_id { + for u in self.users_by_id.values_mut() { u.dirty = false; } - for (_, s) in &mut self.sessions { + for s in self.sessions.values_mut() { s.dirty = false; } } diff --git a/server/db/check.rs b/server/db/check.rs index cb77db6..7aa7f20 100644 --- a/server/db/check.rs +++ b/server/db/check.rs @@ -232,7 +232,7 @@ struct Stream { type Dir = FnvHashMap; fn summarize_index(video_index: &[u8]) -> Result { - let mut it = recording::SampleIndexIterator::new(); + let mut it = recording::SampleIndexIterator::default(); let mut media_duration = 0; let mut video_samples = 0; let mut video_sync_samples = 0; diff --git a/server/db/days.rs b/server/db/days.rs index f013cf8..b9717cc 100644 --- a/server/db/days.rs +++ b/server/db/days.rs @@ -152,17 +152,16 @@ pub struct SignalChange { new_state: u16, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Map(pub(crate) BTreeMap); impl Map { - pub fn new() -> Self { - Self(BTreeMap::new()) - } - pub fn len(&self) -> usize { self.0.len() } + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } pub fn get(&self, k: &Key) -> Option<&V> { self.0.get(k) } @@ -296,9 +295,9 @@ impl Map { self.adjust_day( day, SignalChange { + duration, old_state, new_state, - duration, }, ); @@ -338,7 +337,7 @@ mod tests { #[test] fn test_adjust_stream() { testutil::init(); - let mut m: Map = Map::new(); + let mut m: Map = Map::default(); // Create a day. let test_time = Time(130647162600000i64); // 2015-12-31 23:59:00 (Pacific). @@ -446,7 +445,7 @@ mod tests { #[test] fn test_adjust_signal() { testutil::init(); - let mut m: Map = Map::new(); + let mut m: Map = Map::default(); let test_time = Time(130646844000000i64); // 2015-12-31 23:00:00 (Pacific). let hr = Duration(60 * 60 * TIME_UNITS_PER_SEC); diff --git a/server/db/db.rs b/server/db/db.rs index ea8406a..1b1d312 100644 --- a/server/db/db.rs +++ b/server/db/db.rs @@ -64,7 +64,7 @@ pub const EXPECTED_VERSION: i32 = 6; /// Make it one less than a power of two so that the data structure's size is efficient. const VIDEO_INDEX_CACHE_LEN: usize = 1023; -const GET_RECORDING_PLAYBACK_SQL: &'static str = r#" +const GET_RECORDING_PLAYBACK_SQL: &str = r#" select video_index from @@ -73,14 +73,14 @@ const GET_RECORDING_PLAYBACK_SQL: &'static str = r#" composite_id = :composite_id "#; -const INSERT_VIDEO_SAMPLE_ENTRY_SQL: &'static str = r#" +const INSERT_VIDEO_SAMPLE_ENTRY_SQL: &str = r#" insert into video_sample_entry (width, height, pasp_h_spacing, pasp_v_spacing, rfc6381_codec, data) values (:width, :height, :pasp_h_spacing, :pasp_v_spacing, :rfc6381_codec, :data) "#; -const UPDATE_STREAM_COUNTERS_SQL: &'static str = r#" +const UPDATE_STREAM_COUNTERS_SQL: &str = r#" update stream set cum_recordings = :cum_recordings, cum_media_duration_90k = :cum_media_duration_90k, @@ -231,6 +231,7 @@ pub struct RecordingPlayback<'a> { } /// Bitmask in the `flags` field in the `recordings` table; see `schema.sql`. +#[repr(u32)] pub enum RecordingFlags { TrailingZero = 1, @@ -356,37 +357,37 @@ pub struct Camera { #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum StreamType { - MAIN, - SUB, + Main, + Sub, } impl StreamType { pub fn from_index(i: usize) -> Option { match i { - 0 => Some(StreamType::MAIN), - 1 => Some(StreamType::SUB), + 0 => Some(StreamType::Main), + 1 => Some(StreamType::Sub), _ => None, } } pub fn index(self) -> usize { match self { - StreamType::MAIN => 0, - StreamType::SUB => 1, + StreamType::Main => 0, + StreamType::Sub => 1, } } pub fn as_str(self) -> &'static str { match self { - StreamType::MAIN => "main", - StreamType::SUB => "sub", + StreamType::Main => "main", + StreamType::Sub => "sub", } } pub fn parse(type_: &str) -> Option { match type_ { - "main" => Some(StreamType::MAIN), - "sub" => Some(StreamType::SUB), + "main" => Some(StreamType::Main), + "sub" => Some(StreamType::Sub), _ => None, } } @@ -398,7 +399,7 @@ impl ::std::fmt::Display for StreamType { } } -pub const ALL_STREAM_TYPES: [StreamType; 2] = [StreamType::MAIN, StreamType::SUB]; +pub const ALL_STREAM_TYPES: [StreamType; 2] = [StreamType::Main, StreamType::Sub]; pub struct Stream { pub id: i32, @@ -708,7 +709,7 @@ impl StreamStateChanger { bail!("missing stream {}", sid); } sids[i] = Some(sid); - let sc = mem::replace(*sc, StreamChange::default()); + let sc = mem::take(*sc); streams.push((sid, Some((camera_id, type_, sc)))); } } else { @@ -737,7 +738,7 @@ impl StreamStateChanger { })?; let id = tx.last_insert_rowid() as i32; sids[i] = Some(id); - let sc = mem::replace(*sc, StreamChange::default()); + let sc = mem::take(*sc); streams.push((id, Some((camera_id, type_, sc)))); } } @@ -768,7 +769,7 @@ impl StreamStateChanger { bytes_to_add: 0, fs_bytes_to_add: 0, duration: recording::Duration(0), - committed_days: days::Map::new(), + committed_days: days::Map::default(), record: sc.record, cum_recordings: 0, cum_media_duration: recording::Duration(0), @@ -929,7 +930,7 @@ impl LockedDatabase { /// longer connected). This doesn't work when the system is shutting down and nothing more is /// sent, though. pub fn clear_watches(&mut self) { - for (_, s) in &mut self.streams_by_id { + for s in self.streams_by_id.values_mut() { s.on_live_segment.clear(); } } @@ -1229,14 +1230,11 @@ impl LockedDatabase { /// Gets a given camera by uuid. pub fn get_camera(&self, uuid: Uuid) -> Option<&Camera> { - match self.cameras_by_uuid.get(&uuid) { - Some(id) => Some( - self.cameras_by_id - .get(id) - .expect("uuid->id requires id->cam"), - ), - None => None, - } + self.cameras_by_uuid.get(&uuid).map(|id| { + self.cameras_by_id + .get(id) + .expect("uuid->id requires id->cam") + }) } /// Lists the specified recordings, passing them to a supplied function. Given that the @@ -1439,7 +1437,7 @@ impl LockedDatabase { trace!("cache hit for recording {}", id); occupied.to_back(); let video_index = occupied.get(); - return f(&RecordingPlayback { video_index }); + f(&RecordingPlayback { video_index }) } RawEntryMut::Vacant(vacant) => { trace!("cache miss for recording {}", id); @@ -1602,7 +1600,7 @@ impl LockedDatabase { self.cameras_by_id.insert( id, Camera { - id: id, + id, uuid: uuid.0, short_name: row.get(2)?, description: row.get(3)?, @@ -1671,7 +1669,7 @@ impl LockedDatabase { bytes_to_add: 0, fs_bytes_to_add: 0, duration: recording::Duration(0), - committed_days: days::Map::new(), + committed_days: days::Map::default(), cum_recordings: row.get(7)?, cum_media_duration: recording::Duration(row.get(8)?), cum_runs: row.get(9)?, @@ -1781,7 +1779,7 @@ impl LockedDatabase { garbage_needs_unlink: FnvHashSet::default(), garbage_unlinked: Vec::new(), }), - Entry::Occupied(_) => Err(format_err!("duplicate sample file dir id {}", id))?, + Entry::Occupied(_) => bail!("duplicate sample file dir id {}", id), }; d.last_complete_open = Some(*o); mem::swap(&mut meta.last_complete_open, &mut meta.in_progress_open); @@ -2155,22 +2153,21 @@ pub(crate) fn check_schema_version(conn: &rusqlite::Connection) -> Result<(), Er that predates schema versioning, see guide/schema.md." ) })?; - if ver < EXPECTED_VERSION { - bail!( + match ver.cmp(&EXPECTED_VERSION) { + std::cmp::Ordering::Less => bail!( "Database schema version {} is too old (expected {}); \ see upgrade instructions in guide/upgrade.md.", ver, EXPECTED_VERSION - ); - } else if ver > EXPECTED_VERSION { - bail!( + ), + std::cmp::Ordering::Equal => Ok(()), + std::cmp::Ordering::Greater => bail!( "Database schema version {} is too new (expected {}); \ must use a newer binary to match.", ver, EXPECTED_VERSION - ); + ), } - Ok(()) } /// The recording database. Abstracts away SQLite queries. Also maintains in-memory state diff --git a/server/db/dir.rs b/server/db/dir.rs index 275b955..e84fa5e 100644 --- a/server/db/dir.rs +++ b/server/db/dir.rs @@ -355,9 +355,9 @@ pub(crate) fn parse_id(id: &[u8]) -> Result { return Err(()); } let mut v: u64 = 0; - for i in 0..16 { + for b in id { v = (v << 4) - | match id[i] { + | match b { b @ b'0'..=b'9' => b - b'0', b @ b'a'..=b'f' => b - b'a' + 10, _ => return Err(()), diff --git a/server/db/raw.rs b/server/db/raw.rs index b7dc07e..cbc4f62 100644 --- a/server/db/raw.rs +++ b/server/db/raw.rs @@ -13,7 +13,7 @@ use std::ops::Range; use uuid::Uuid; // Note: the magic number "27000000" below is recording::MAX_RECORDING_DURATION. -const LIST_RECORDINGS_BY_TIME_SQL: &'static str = r#" +const LIST_RECORDINGS_BY_TIME_SQL: &str = r#" select recording.composite_id, recording.run_offset, @@ -37,7 +37,7 @@ const LIST_RECORDINGS_BY_TIME_SQL: &'static str = r#" recording.start_time_90k "#; -const LIST_RECORDINGS_BY_ID_SQL: &'static str = r#" +const LIST_RECORDINGS_BY_ID_SQL: &str = r#" select recording.composite_id, recording.run_offset, @@ -61,7 +61,7 @@ const LIST_RECORDINGS_BY_ID_SQL: &'static str = r#" recording.composite_id "#; -const STREAM_MIN_START_SQL: &'static str = r#" +const STREAM_MIN_START_SQL: &str = r#" select start_time_90k from @@ -71,7 +71,7 @@ const STREAM_MIN_START_SQL: &'static str = r#" order by start_time_90k limit 1 "#; -const STREAM_MAX_START_SQL: &'static str = r#" +const STREAM_MAX_START_SQL: &str = r#" select start_time_90k, wall_duration_90k @@ -82,7 +82,7 @@ const STREAM_MAX_START_SQL: &'static str = r#" order by start_time_90k desc; "#; -const LIST_OLDEST_RECORDINGS_SQL: &'static str = r#" +const LIST_OLDEST_RECORDINGS_SQL: &str = r#" select composite_id, start_time_90k, diff --git a/server/db/recording.rs b/server/db/recording.rs index 0473ecc..5ee3934 100644 --- a/server/db/recording.rs +++ b/server/db/recording.rs @@ -50,7 +50,7 @@ pub fn rescale(from_off_90k: i32, from_duration_90k: i32, to_duration_90k: i32) /// An iterator through a sample index (as described in `design/recording.md`). /// Initially invalid; call `next()` before each read. -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Default)] pub struct SampleIndexIterator { /// The index byte position of the next sample to read (low 31 bits) and if the current /// same is a key frame (high bit). @@ -74,17 +74,6 @@ pub struct SampleIndexIterator { } impl SampleIndexIterator { - pub fn new() -> SampleIndexIterator { - SampleIndexIterator { - i_and_is_key: 0, - pos: 0, - start_90k: 0, - duration_90k: 0, - bytes: 0, - bytes_other: 0, - } - } - pub fn next(&mut self, data: &[u8]) -> Result { self.pos += self.bytes; self.start_90k += self.duration_90k; @@ -147,7 +136,7 @@ impl SampleIndexIterator { } /// An encoder for a sample index (as described in `design/recording.md`). -#[derive(Debug)] +#[derive(Debug, Default)] pub struct SampleIndexEncoder { prev_duration_90k: i32, prev_bytes_key: i32, @@ -155,14 +144,6 @@ pub struct SampleIndexEncoder { } impl SampleIndexEncoder { - pub fn new() -> Self { - SampleIndexEncoder { - prev_duration_90k: 0, - prev_bytes_key: 0, - prev_bytes_nonkey: 0, - } - } - pub fn add_sample( &mut self, duration_90k: i32, @@ -205,7 +186,7 @@ pub struct Segment { /// An iterator positioned at the beginning of the segment, or `None`. Most segments are /// positioned at the beginning of the recording, so this is an optional box to shrink a long - /// of segments. `None` is equivalent to `SampleIndexIterator::new()`. + /// of segments. `None` is equivalent to `SampleIndexIterator::default()`. begin: Option>, pub file_end: i32, @@ -246,6 +227,7 @@ impl Segment { << 31), }; + #[allow(clippy::suspicious_operation_groupings)] if desired_media_range_90k.start > desired_media_range_90k.end || desired_media_range_90k.end > recording.media_duration_90k { @@ -275,9 +257,9 @@ impl Segment { recording ); db.with_recording_playback(self_.id, &mut |playback| { - let mut begin = Box::new(SampleIndexIterator::new()); - let data = &(&playback).video_index; - let mut it = SampleIndexIterator::new(); + let mut begin = Box::new(SampleIndexIterator::default()); + let data = &playback.video_index; + let mut it = SampleIndexIterator::default(); if !it.next(data)? { bail!("no index"); } @@ -352,11 +334,11 @@ impl Segment { self.frames, self.actual_start_90k() ); - let data = &(&playback).video_index; + let data = &playback.video_index; let mut it = match self.begin { Some(ref b) => **b, None => { - let mut it = SampleIndexIterator::new(); + let mut it = SampleIndexIterator::default(); if !it.next(data)? { bail!("recording {} has no frames", self.id); } @@ -434,7 +416,7 @@ mod tests { fn test_encode_example() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut e = SampleIndexEncoder::new(); + let mut e = SampleIndexEncoder::default(); e.add_sample(10, 1000, true, &mut r); e.add_sample(9, 10, false, &mut r); e.add_sample(11, 15, false, &mut r); @@ -468,11 +450,11 @@ mod tests { Sample { duration_90k: 0, bytes: 1000, is_key: false, }, ]; let mut r = db::RecordingToInsert::default(); - let mut e = SampleIndexEncoder::new(); + let mut e = SampleIndexEncoder::default(); for sample in &samples { e.add_sample(sample.duration_90k, sample.bytes, sample.is_key, &mut r); } - let mut it = SampleIndexIterator::new(); + let mut it = SampleIndexIterator::default(); for sample in &samples { assert!(it.next(&r.video_index).unwrap()); assert_eq!( @@ -519,7 +501,7 @@ mod tests { }, ]; for test in &tests { - let mut it = SampleIndexIterator::new(); + let mut it = SampleIndexIterator::default(); assert_eq!(it.next(test.encoded).unwrap_err().to_string(), test.err); } } @@ -546,7 +528,7 @@ mod tests { fn test_segment_clipping_with_all_sync() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -568,7 +550,7 @@ mod tests { fn test_segment_clipping_with_half_sync() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -586,7 +568,7 @@ mod tests { fn test_segment_clipping_with_trailing_zero() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); encoder.add_sample(1, 1, true, &mut r); encoder.add_sample(1, 2, true, &mut r); encoder.add_sample(0, 3, true, &mut r); @@ -601,7 +583,7 @@ mod tests { fn test_segment_zero_desired_duration() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); encoder.add_sample(1, 1, true, &mut r); let db = TestDb::new(RealClocks {}); let row = db.insert_recording_from_encoder(r); @@ -615,7 +597,7 @@ mod tests { fn test_segment_fast_path() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -634,7 +616,7 @@ mod tests { fn test_segment_fast_path_with_trailing_zero() { testutil::init(); let mut r = db::RecordingToInsert::default(); - let mut encoder = SampleIndexEncoder::new(); + let mut encoder = SampleIndexEncoder::default(); encoder.add_sample(1, 1, true, &mut r); encoder.add_sample(1, 2, true, &mut r); encoder.add_sample(0, 3, true, &mut r); @@ -659,7 +641,7 @@ mod bench { let data = include_bytes!("testdata/video_sample_index.bin"); b.bytes = data.len() as u64; b.iter(|| { - let mut it = SampleIndexIterator::new(); + let mut it = SampleIndexIterator::default(); while it.next(data).unwrap() {} assert_eq!(30104460, it.pos); assert_eq!(5399985, it.start_90k); diff --git a/server/db/signal.rs b/server/db/signal.rs index cc7f3c1..39fcce8 100644 --- a/server/db/signal.rs +++ b/server/db/signal.rs @@ -167,7 +167,7 @@ impl<'a> PointDataIterator<'a> { Ok(Some((signal, state as u16))) } - fn to_map(mut self) -> Result, Error> { + fn into_map(mut self) -> Result, Error> { let mut out = BTreeMap::new(); while let Some((signal, state)) = self.next()? { out.insert(signal, state); @@ -291,7 +291,7 @@ impl State { fn gc(&mut self) { let max = match self.max_signal_changes { None => return, - Some(m) if m < 0 => 0 as usize, + Some(m) if m < 0 => 0_usize, Some(m) if m > (isize::max_value() as i64) => return, Some(m) => m as usize, }; @@ -311,7 +311,7 @@ impl State { .points_by_time .keys() .take(to_remove) - .map(|t| *t) + .copied() .collect(); for t in &remove { @@ -406,7 +406,7 @@ impl State { if let Some((&t, ref mut p)) = self.points_by_time.range_mut(..=when.end).next_back() { if t == when.end { // Already have a point at end. Adjust it. prev starts unchanged... - prev = p.prev().to_map().expect("in-mem prev is valid"); + prev = p.prev().into_map().expect("in-mem prev is valid"); // ...and then prev and changes are altered to reflect the desired update. State::update_signals_end_maps( @@ -505,8 +505,8 @@ impl State { if let Some((&t, ref mut p)) = self.points_by_time.range_mut(..=start).next_back() { if t == start { // Reuse existing point at start. - prev = p.prev().to_map().expect("in-mem prev is valid"); - let mut changes = p.changes().to_map().expect("in-mem changes is valid"); + prev = p.prev().into_map().expect("in-mem prev is valid"); + let mut changes = p.changes().into_map().expect("in-mem changes is valid"); let mut dirty = false; for (&signal, &state) in signals.iter().zip(states) { match changes.entry(signal) { @@ -570,7 +570,7 @@ impl State { let after_start = recording::Time(when.start.0 + 1); let mut prev_t = when.start; for (&t, ref mut p) in self.points_by_time.range_mut(after_start..when.end) { - let mut prev = p.prev().to_map().expect("in-mem prev is valid"); + let mut prev = p.prev().into_map().expect("in-mem prev is valid"); // Update prev to reflect desired update; likewise each signal's days index. for (&signal, &state) in signals.iter().zip(states) { @@ -691,7 +691,7 @@ impl State { type_: type_.0, short_name: row.get(3)?, cameras: Vec::new(), - days: days::Map::new(), + days: days::Map::default(), }, ); } @@ -837,7 +837,7 @@ impl State { fn debug_assert_point_invariants(&self) { let mut expected_prev = BTreeMap::new(); for (t, p) in self.points_by_time.iter() { - let cur = p.prev().to_map().expect("in-mem prev is valid"); + let cur = p.prev().into_map().expect("in-mem prev is valid"); assert_eq!(&expected_prev, &cur, "time {} prev mismatch", t); p.changes().update_map(&mut expected_prev); } @@ -973,7 +973,7 @@ mod tests { &mut |_r| panic!("no changes expected"), ); assert_eq!(&rows[..], EXPECTED); - let mut expected_days = days::Map::new(); + let mut expected_days = days::Map::default(); expected_days.0.insert( days::Key(*b"2019-04-26"), days::SignalValue { diff --git a/server/db/testutil.rs b/server/db/testutil.rs index 77d05fe..5c81185 100644 --- a/server/db/testutil.rs +++ b/server/db/testutil.rs @@ -10,13 +10,10 @@ use crate::dir; use crate::writer; use base::clock::Clocks; use fnv::FnvHashMap; -use mylog; -use rusqlite; use std::env; use std::sync::Arc; use std::thread; use tempfile::TempDir; -use time; use uuid::Uuid; static INIT: parking_lot::Once = parking_lot::Once::new(); @@ -42,7 +39,7 @@ pub const TEST_VIDEO_SAMPLE_ENTRY_DATA: &[u8] = pub fn init() { INIT.call_once(|| { let h = mylog::Builder::new() - .set_spec(&::std::env::var("MOONFIRE_LOG").unwrap_or("info".to_owned())) + .set_spec(&::std::env::var("MOONFIRE_LOG").unwrap_or_else(|_| "info".to_owned())) .build(); h.install().unwrap(); env::set_var("TZ", "America/Los_Angeles"); @@ -80,7 +77,7 @@ impl TestDb { let dir; { let mut l = db.lock(); - sample_file_dir_id = l.add_sample_file_dir(path.to_owned()).unwrap(); + sample_file_dir_id = l.add_sample_file_dir(path).unwrap(); assert_eq!( TEST_CAMERA_ID, l.add_camera(db::CameraChange { @@ -116,7 +113,7 @@ impl TestDb { .unwrap(); } let mut dirs_by_stream_id = FnvHashMap::default(); - dirs_by_stream_id.insert(TEST_STREAM_ID, dir.clone()); + dirs_by_stream_id.insert(TEST_STREAM_ID, dir); let (syncer_channel, syncer_join) = writer::start_syncer(db.clone(), sample_file_dir_id).unwrap(); TestDb { diff --git a/server/db/upgrade/mod.rs b/server/db/upgrade/mod.rs index 6dc0f23..0f5a191 100644 --- a/server/db/upgrade/mod.rs +++ b/server/db/upgrade/mod.rs @@ -22,8 +22,7 @@ mod v3_to_v4; mod v4_to_v5; mod v5_to_v6; -const UPGRADE_NOTES: &'static str = - concat!("upgraded using moonfire-db ", env!("CARGO_PKG_VERSION")); +const UPGRADE_NOTES: &str = concat!("upgraded using moonfire-db ", env!("CARGO_PKG_VERSION")); #[derive(Debug)] pub struct Args<'a> { diff --git a/server/db/upgrade/v0_to_v1.rs b/server/db/upgrade/v0_to_v1.rs index ad06474..052694b 100644 --- a/server/db/upgrade/v0_to_v1.rs +++ b/server/db/upgrade/v0_to_v1.rs @@ -99,7 +99,7 @@ struct CameraState { } fn has_trailing_zero(video_index: &[u8]) -> Result { - let mut it = recording::SampleIndexIterator::new(); + let mut it = recording::SampleIndexIterator::default(); while it.next(video_index)? {} Ok(it.duration_90k == 0) } diff --git a/server/db/upgrade/v2_to_v3.rs b/server/db/upgrade/v2_to_v3.rs index 44d5dcd..0a50845 100644 --- a/server/db/upgrade/v2_to_v3.rs +++ b/server/db/upgrade/v2_to_v3.rs @@ -77,7 +77,7 @@ pub fn run(_args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error> if e == nix::Error::Sys(nix::errno::Errno::ENOENT) { continue; // assume it was already moved. } - Err(e)?; + return Err(e.into()); } } diff --git a/server/db/writer.rs b/server/db/writer.rs index dc48ba3..4cb57f4 100644 --- a/server/db/writer.rs +++ b/server/db/writer.rs @@ -358,7 +358,7 @@ impl Syncer> { /// Called from main thread. fn initial_rotation(&mut self) -> Result<(), Error> { self.do_rotation(|db| { - let streams: Vec = db.streams_by_id().keys().map(|&id| id).collect(); + let streams: Vec = db.streams_by_id().keys().copied().collect(); for &stream_id in &streams { delete_recordings(db, stream_id, 0)?; } @@ -379,7 +379,7 @@ impl Syncer> { let mut garbage: Vec<_> = { let l = self.db.lock(); let d = l.sample_file_dirs_by_id().get(&self.dir_id).unwrap(); - d.garbage_needs_unlink.iter().map(|id| *id).collect() + d.garbage_needs_unlink.iter().copied().collect() }; if !garbage.is_empty() { // Try to delete files; retain ones in `garbage` that don't exist. @@ -422,7 +422,9 @@ impl Syncer { let now = self.db.clocks().monotonic(); // Calculate the timeout to use, mapping negative durations to 0. - let timeout = (t - now).to_std().unwrap_or(StdDuration::new(0, 0)); + let timeout = (t - now) + .to_std() + .unwrap_or_else(|_| StdDuration::new(0, 0)); match self.db.clocks().recv_timeout(&cmds, timeout) { Err(mpsc::RecvTimeoutError::Disconnected) => return false, // cmd senders gone. Err(mpsc::RecvTimeoutError::Timeout) => { @@ -456,7 +458,7 @@ impl Syncer { let mut garbage: Vec<_> = { let l = self.db.lock(); let d = l.sample_file_dirs_by_id().get(&self.dir_id).unwrap(); - d.garbage_needs_unlink.iter().map(|id| *id).collect() + d.garbage_needs_unlink.iter().copied().collect() }; if garbage.is_empty() { return; @@ -691,7 +693,7 @@ impl<'a, C: Clocks + Clone, D: DirWriter> Writer<'a, C, D> { self.state = WriterState::Open(InnerWriter { f, r, - e: recording::SampleIndexEncoder::new(), + e: recording::SampleIndexEncoder::default(), id, hasher: blake3::Hasher::new(), local_start: recording::Time(i64::max_value()), @@ -878,7 +880,7 @@ impl InnerWriter { let mut l = self.r.lock(); l.flags = flags; l.local_time_delta = self.local_start - l.start; - l.sample_file_blake3 = Some(blake3.as_bytes().clone()); + l.sample_file_blake3 = Some(*blake3.as_bytes()); wall_duration = recording::Duration(i64::from(l.wall_duration_90k)); run_offset = l.run_offset; end = l.start + wall_duration; diff --git a/server/src/body.rs b/server/src/body.rs index c1774e5..257222e 100644 --- a/server/src/body.rs +++ b/server/src/body.rs @@ -40,13 +40,13 @@ impl From<&'static str> for Chunk { impl From for Chunk { fn from(r: String) -> Self { - Chunk(ARefss::new(r.into_bytes()).map(|v| &v[..])) + Chunk(ARefss::new(r.into_bytes())) } } impl From> for Chunk { fn from(r: Vec) -> Self { - Chunk(ARefss::new(r).map(|v| &v[..])) + Chunk(ARefss::new(r)) } } diff --git a/server/src/cmds/config/cameras.rs b/server/src/cmds/config/cameras.rs index 327de16..fe068c5 100644 --- a/server/src/cmds/config/cameras.rs +++ b/server/src/cmds/config/cameras.rs @@ -279,7 +279,7 @@ fn lower_retention( db: &Arc, zero_limits: BTreeMap>, ) -> Result<(), Error> { - let dirs_to_open: Vec<_> = zero_limits.keys().map(|id| *id).collect(); + let dirs_to_open: Vec<_> = zero_limits.keys().copied().collect(); db.lock().open_sample_file_dirs(&dirs_to_open[..])?; for (&dir_id, l) in &zero_limits { writer::lower_retention(db.clone(), dir_id, &l)?; @@ -358,7 +358,7 @@ fn edit_camera_dialog(db: &Arc, siv: &mut Cursive, item: &Option>::new() - .with_all(dirs.iter().map(|d| d.clone())) + .with_all(dirs.iter().cloned()) .popup() .with_name(format!("{}_sample_file_dir", type_.as_str())), ) diff --git a/server/src/cmds/config/dirs.rs b/server/src/cmds/config/dirs.rs index 823fd40..4d787b4 100644 --- a/server/src/cmds/config/dirs.rs +++ b/server/src/cmds/config/dirs.rs @@ -408,10 +408,7 @@ fn edit_dir_dialog(db: &Arc, siv: &mut Cursive, dir_id: i32) { .child(views::DummyView {}.fixed_width(20)) .child(views::TextView::new(encode_size(model.borrow().fs_capacity)).fixed_width(25)), ); - let mut change_button = views::Button::new("Change", { - let model = model.clone(); - move |siv| press_change(&model, siv) - }); + let mut change_button = views::Button::new("Change", move |siv| press_change(&model, siv)); change_button.set_enabled(!over); let mut buttons = views::LinearLayout::horizontal().child(views::DummyView.full_width()); buttons.add_child(change_button.with_name("change")); diff --git a/server/src/cmds/config/mod.rs b/server/src/cmds/config/mod.rs index 0487ffe..7dba29b 100644 --- a/server/src/cmds/config/mod.rs +++ b/server/src/cmds/config/mod.rs @@ -10,7 +10,6 @@ use base::clock; use cursive::views; use cursive::Cursive; -use db; use failure::Error; use std::path::PathBuf; use std::sync::Arc; @@ -43,10 +42,7 @@ pub fn run(args: &Args) -> Result { siv.add_layer( views::Dialog::around( views::SelectView::, &mut Cursive)>::new() - .on_submit({ - let db = db.clone(); - move |siv, item| item(&db, siv) - }) + .on_submit(move |siv, item| item(&db, siv)) .item("Cameras and streams".to_string(), cameras::top_dialog) .item("Directories and retention".to_string(), dirs::top_dialog) .item("Users".to_string(), users::top_dialog), diff --git a/server/src/cmds/config/users.rs b/server/src/cmds/config/users.rs index 79d586e..e4a41f3 100644 --- a/server/src/cmds/config/users.rs +++ b/server/src/cmds/config/users.rs @@ -126,12 +126,12 @@ fn edit_user_dialog(db: &Arc, siv: &mut Cursive, item: Option { let l = db.lock(); let u = item.map(|id| l.users_by_id().get(&id).unwrap()); - username = u.map(|u| u.username.clone()).unwrap_or(String::new()); - id_str = item.map(|id| id.to_string()).unwrap_or("".to_string()); + username = u.map(|u| u.username.clone()).unwrap_or_default(); + id_str = item + .map(|id| id.to_string()) + .unwrap_or_else(|| "".to_string()); has_password = u.map(|u| u.has_password()).unwrap_or(false); - permissions = u - .map(|u| u.permissions.clone()) - .unwrap_or(db::Permissions::default()); + permissions = u.map(|u| u.permissions.clone()).unwrap_or_default(); } let top_list = views::ListView::new() .child("id", views::TextView::new(id_str)) diff --git a/server/src/cmds/login.rs b/server/src/cmds/login.rs index 82dcf11..9b23005 100644 --- a/server/src/cmds/login.rs +++ b/server/src/cmds/login.rs @@ -56,7 +56,7 @@ pub struct Args { pub fn run(args: &Args) -> Result { let clocks = clock::RealClocks {}; let (_db_dir, conn) = super::open_conn(&args.db_dir, super::OpenMode::ReadWrite)?; - let db = std::sync::Arc::new(db::Database::new(clocks.clone(), conn, true).unwrap()); + let db = std::sync::Arc::new(db::Database::new(clocks, conn, true).unwrap()); let mut l = db.lock(); let u = l .get_user(&args.username) @@ -72,7 +72,6 @@ pub fn run(args: &Args) -> Result { flags |= *f as i32; } let uid = u.id; - drop(u); let (sid, _) = l.make_session( creation, uid, diff --git a/server/src/cmds/mod.rs b/server/src/cmds/mod.rs index d16b5c9..dd0b7f4 100644 --- a/server/src/cmds/mod.rs +++ b/server/src/cmds/mod.rs @@ -6,7 +6,6 @@ use db::dir; use failure::{Error, Fail}; use log::info; use nix::fcntl::FlockArg; -use rusqlite; use std::path::Path; pub mod check; diff --git a/server/src/cmds/run.rs b/server/src/cmds/run.rs index a38dd9c..3efe986 100644 --- a/server/src/cmds/run.rs +++ b/server/src/cmds/run.rs @@ -17,7 +17,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::thread; use structopt::StructOpt; -use tokio; use tokio::signal::unix::{signal, SignalKind}; #[derive(StructOpt)] @@ -76,20 +75,20 @@ pub struct Args { // These are used in a hack to get the name of the current time zone (e.g. America/Los_Angeles). // They seem to be correct for Linux and macOS at least. -const LOCALTIME_PATH: &'static str = "/etc/localtime"; -const TIMEZONE_PATH: &'static str = "/etc/timezone"; -const ZONEINFO_PATHS: [&'static str; 2] = [ +const LOCALTIME_PATH: &str = "/etc/localtime"; +const TIMEZONE_PATH: &str = "/etc/timezone"; +const ZONEINFO_PATHS: [&str; 2] = [ "/usr/share/zoneinfo/", // Linux, macOS < High Sierra "/var/db/timezone/zoneinfo/", // macOS High Sierra ]; -fn trim_zoneinfo(p: &str) -> &str { +fn trim_zoneinfo(path: &str) -> &str { for zp in &ZONEINFO_PATHS { - if p.starts_with(zp) { - return &p[zp.len()..]; + if let Some(p) = path.strip_prefix(zp) { + return p; } } - return p; + path } /// Attempt to resolve the timezone of the server. @@ -145,7 +144,7 @@ fn resolve_zone() -> Result { // If `TIMEZONE_PATH` is a file, use its contents as the zone name. match ::std::fs::read_to_string(TIMEZONE_PATH) { - Ok(z) => return Ok(z), + Ok(z) => Ok(z), Err(e) => { bail!( "Unable to resolve timezone from TZ env, {}, or {}. Last error: {}", @@ -174,7 +173,7 @@ pub async fn run(args: &Args) -> Result { super::OpenMode::ReadWrite }, )?; - let db = Arc::new(db::Database::new(clocks.clone(), conn, !args.read_only).unwrap()); + let db = Arc::new(db::Database::new(clocks, conn, !args.read_only).unwrap()); info!("Database is loaded."); let object_detector = match args.object_detection { @@ -260,7 +259,7 @@ pub async fn run(args: &Args) -> Result { let rotate_offset_sec = streamer::ROTATE_INTERVAL_SEC * i as i64 / streams as i64; let syncer = syncers.get(&sample_file_dir_id).unwrap(); let object_detector = match stream.type_ { - db::StreamType::SUB => object_detector.clone(), + db::StreamType::Sub => object_detector.clone(), _ => None, }; let mut streamer = streamer::Streamer::new( diff --git a/server/src/cmds/upgrade/mod.rs b/server/src/cmds/upgrade/mod.rs index 4810278..642c3a6 100644 --- a/server/src/cmds/upgrade/mod.rs +++ b/server/src/cmds/upgrade/mod.rs @@ -45,10 +45,7 @@ pub fn run(args: &Args) -> Result { db::upgrade::run( &db::upgrade::Args { - sample_file_dir: args - .sample_file_dir - .as_ref() - .map(std::path::PathBuf::as_path), + sample_file_dir: args.sample_file_dir.as_deref(), preset_journal: &args.preset_journal, no_vacuum: args.no_vacuum, }, diff --git a/server/src/json.rs b/server/src/json.rs index f87efb8..35b207a 100644 --- a/server/src/json.rs +++ b/server/src/json.rs @@ -208,7 +208,7 @@ impl<'a> Camera<'a> { { let mut map = serializer.serialize_map(Some(streams.len()))?; for (i, s) in streams.iter().enumerate() { - if let &Some(ref s) = s { + if let Some(ref s) = *s { map.serialize_key( db::StreamType::from_index(i) .expect("invalid stream type index") @@ -397,10 +397,9 @@ impl<'a> TopLevel<'a> { let (db, include_days, include_config) = *cameras; let cs = db.cameras_by_id(); let mut seq = serializer.serialize_seq(Some(cs.len()))?; - for (_, c) in cs { + for c in cs.values() { seq.serialize_element( - &Camera::wrap(c, db, include_days, include_config) - .map_err(|e| S::Error::custom(e))?, + &Camera::wrap(c, db, include_days, include_config).map_err(S::Error::custom)?, )?; } seq.end() @@ -417,7 +416,7 @@ impl<'a> TopLevel<'a> { let (db, include_days) = *signals; let ss = db.signals_by_id(); let mut seq = serializer.serialize_seq(Some(ss.len()))?; - for (_, s) in ss { + for s in ss.values() { seq.serialize_element(&Signal::wrap(s, db, include_days))?; } seq.end() diff --git a/server/src/main.rs b/server/src/main.rs index d703dfd..6983042 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -160,7 +160,7 @@ fn main() { .and_then(|s| mylog::ColorMode::from_str(&s)) .unwrap_or(mylog::ColorMode::Auto), ) - .set_spec(&::std::env::var("MOONFIRE_LOG").unwrap_or("info".to_owned())) + .set_spec(&::std::env::var("MOONFIRE_LOG").unwrap_or_else(|_| "info".to_owned())) .build(); h.clone().install().unwrap(); diff --git a/server/src/mp4.rs b/server/src/mp4.rs index 31b3ea1..976c239 100644 --- a/server/src/mp4.rs +++ b/server/src/mp4.rs @@ -63,12 +63,9 @@ use db::dir; use db::recording::{self, rescale, TIME_UNITS_PER_SEC}; use futures::stream; use futures::Stream; -use http; use http::header::HeaderValue; -use http_serve; use hyper::body::Buf; use log::{debug, error, trace, warn}; -use memmap; use parking_lot::Once; use reffers::ARefss; use smallvec::SmallVec; @@ -88,7 +85,7 @@ use std::time::SystemTime; const FORMAT_VERSION: [u8; 1] = [0x08]; /// An `ftyp` (ISO/IEC 14496-12 section 4.3 `FileType`) box. -const NORMAL_FTYP_BOX: &'static [u8] = &[ +const NORMAL_FTYP_BOX: &[u8] = &[ 0x00, 0x00, 0x00, 0x20, // length = 32, sizeof(NORMAL_FTYP_BOX) b'f', b't', b'y', b'p', // type b'i', b's', b'o', b'm', // major_brand @@ -105,7 +102,7 @@ const NORMAL_FTYP_BOX: &'static [u8] = &[ /// (8.8.7.1) cannot be set where a file is marked with [the avc1 brand]." /// Note that Safari insists there be a compatible brand set in this list. The /// major brand is not enough. -const INIT_SEGMENT_FTYP_BOX: &'static [u8] = &[ +const INIT_SEGMENT_FTYP_BOX: &[u8] = &[ 0x00, 0x00, 0x00, 0x14, // length = 20, sizeof(INIT_SEGMENT_FTYP_BOX) b'f', b't', b'y', b'p', // type b'i', b's', b'o', b'5', // major_brand @@ -114,7 +111,7 @@ const INIT_SEGMENT_FTYP_BOX: &'static [u8] = &[ ]; /// An `hdlr` (ISO/IEC 14496-12 section 8.4.3 `HandlerBox`) box suitable for video. -const VIDEO_HDLR_BOX: &'static [u8] = &[ +const VIDEO_HDLR_BOX: &[u8] = &[ 0x00, 0x00, 0x00, 0x21, // length == sizeof(kHdlrBox) b'h', b'd', b'l', b'r', // type == hdlr, ISO/IEC 14496-12 section 8.4.3. 0x00, 0x00, 0x00, 0x00, // version + flags @@ -127,7 +124,7 @@ const VIDEO_HDLR_BOX: &'static [u8] = &[ ]; /// An `hdlr` (ISO/IEC 14496-12 section 8.4.3 `HandlerBox`) box suitable for subtitles. -const SUBTITLE_HDLR_BOX: &'static [u8] = &[ +const SUBTITLE_HDLR_BOX: &[u8] = &[ 0x00, 0x00, 0x00, 0x21, // length == sizeof(kHdlrBox) b'h', b'd', b'l', b'r', // type == hdlr, ISO/IEC 14496-12 section 8.4.3. 0x00, 0x00, 0x00, 0x00, // version + flags @@ -141,7 +138,7 @@ const SUBTITLE_HDLR_BOX: &'static [u8] = &[ /// Part of an `mvhd` (`MovieHeaderBox` version 0, ISO/IEC 14496-12 section 8.2.2), used from /// `append_mvhd`. -const MVHD_JUNK: &'static [u8] = &[ +const MVHD_JUNK: &[u8] = &[ 0x00, 0x01, 0x00, 0x00, // rate 0x01, 0x00, // volume 0x00, 0x00, // reserved @@ -166,7 +163,7 @@ const MVHD_JUNK: &'static [u8] = &[ /// Part of a `tkhd` (`TrackHeaderBox` version 0, ISO/IEC 14496-12 section 8.3.2), used from /// `append_video_tkhd` and `append_subtitle_tkhd`. -const TKHD_JUNK: &'static [u8] = &[ +const TKHD_JUNK: &[u8] = &[ 0x00, 0x00, 0x00, 0x00, // reserved 0x00, 0x00, 0x00, 0x00, // reserved 0x00, 0x00, 0x00, 0x00, // layer + alternate_group @@ -184,7 +181,7 @@ const TKHD_JUNK: &'static [u8] = &[ /// Part of a `minf` (`MediaInformationBox`, ISO/IEC 14496-12 section 8.4.4), used from /// `append_video_minf`. -const VIDEO_MINF_JUNK: &'static [u8] = &[ +const VIDEO_MINF_JUNK: &[u8] = &[ b'm', b'i', b'n', b'f', // type = minf, ISO/IEC 14496-12 section 8.4.4. // A vmhd box; the "graphicsmode" and "opcolor" values don't have any // meaningful use. @@ -208,7 +205,7 @@ const VIDEO_MINF_JUNK: &'static [u8] = &[ /// Part of a `minf` (`MediaInformationBox`, ISO/IEC 14496-12 section 8.4.4), used from /// `append_subtitle_minf`. -const SUBTITLE_MINF_JUNK: &'static [u8] = &[ +const SUBTITLE_MINF_JUNK: &[u8] = &[ b'm', b'i', b'n', b'f', // type = minf, ISO/IEC 14496-12 section 8.4.4. // A nmhd box. 0x00, 0x00, 0x00, 0x0c, // length == sizeof(kNmhdBox) @@ -230,7 +227,7 @@ const SUBTITLE_MINF_JUNK: &'static [u8] = &[ /// Part of a `stbl` (`SampleTableBox`, ISO/IEC 14496 section 8.5.1) used from /// `append_subtitle_stbl`. #[rustfmt::skip] -const SUBTITLE_STBL_JUNK: &'static [u8] = &[ +const SUBTITLE_STBL_JUNK: &[u8] = &[ b's', b't', b'b', b'l', // type = stbl, ISO/IEC 14496-12 section 8.5.1. // A stsd box. 0x00, 0x00, 0x00, 0x54, // length @@ -270,7 +267,7 @@ const SUBTITLE_STBL_JUNK: &'static [u8] = &[ /// Pointers to each static bytestrings. /// The order here must match the `StaticBytestring` enum. -const STATIC_BYTESTRINGS: [&'static [u8]; 9] = [ +const STATIC_BYTESTRINGS: [&[u8]; 9] = [ NORMAL_FTYP_BOX, INIT_SEGMENT_FTYP_BOX, VIDEO_HDLR_BOX, @@ -301,7 +298,7 @@ enum StaticBytestring { /// The template fed into strtime for a timestamp subtitle. This must produce fixed-length output /// (see `SUBTITLE_LENGTH`) to allow quick calculation of the total size of the subtitles for /// a given time range. -const SUBTITLE_TEMPLATE: &'static str = "%Y-%m-%d %H:%M:%S %z"; +const SUBTITLE_TEMPLATE: &str = "%Y-%m-%d %H:%M:%S %z"; /// The length of the output of `SUBTITLE_TEMPLATE`. const SUBTITLE_LENGTH: usize = 25; // "2015-07-02 17:10:00 -0700".len(); @@ -419,7 +416,7 @@ impl Segment { }); let index: &'a _ = unsafe { &*self.index.get() }; match *index { - Ok(ref b) => return Ok(f(&b[..], self.lens())), + Ok(ref b) => Ok(f(&b[..], self.lens())), Err(()) => bail_t!(Unknown, "Unable to build index; see previous error."), } } @@ -562,6 +559,7 @@ impl Segment { if is_key { // first_sample_flags. See trex (8.8.3.1). + #[allow(clippy::identity_op)] v.write_u32::( // As defined by the Independent and Disposable Samples Box // (sdp, 8.6.4). @@ -571,8 +569,7 @@ impl Segment { (2 << 20) | // sample_has_redundancy: no redundant coding // As defined by the sample padding bits (padb, 8.7.6). (0 << 17) | // no padding - (0 << 16) | // sample_is_non_sync_sample=0 - 0, + (0 << 16), // sample_is_non_sync_sample=0 )?; // TODO: sample_degradation_priority } RunInfo { @@ -767,7 +764,7 @@ impl slices::Slice for Slice { type Chunk = Chunk; fn end(&self) -> u64 { - return self.0 & 0xFF_FF_FF_FF_FF; + self.0 & 0xFF_FF_FF_FF_FF } fn get_range( &self, @@ -809,7 +806,7 @@ impl slices::Slice for Slice { SliceType::Truns => self.wrap_truns(f, range.clone(), len as usize), }; Box::new(stream::once(futures::future::ready( - res.map_err(|e| wrap_error(e)).and_then(move |c| { + res.map_err(wrap_error).and_then(move |c| { if c.remaining() != (range.end - range.start) as usize { return Err(wrap_error(format_err_t!( Internal, @@ -884,7 +881,7 @@ impl FileBuilder { buf: Vec::new(), unflushed_buf_pos: 0, }, - type_: type_, + type_, include_timestamp_subtitle_track: false, content_disposition: None, prev_media_duration_and_cur_runs: None, @@ -1822,7 +1819,7 @@ impl FileInner { Ok(ARefss::new(mmap).map(|m| m.deref()).into()) } - fn get_subtitle_sample_data(&self, i: usize, r: Range, l: u64) -> Result { + fn get_subtitle_sample_data(&self, i: usize, r: Range, len: u64) -> Result { let s = &self.segments[i]; let md = &s.rel_media_range_90k; let wd = s.wall(md.start)..s.wall(md.end); @@ -1831,8 +1828,8 @@ impl FileInner { let end_sec = (s.recording_start + recording::Duration(i64::from(wd.end) + TIME_UNITS_PER_SEC - 1)) .unix_seconds(); - let l = usize::try_from(l).unwrap(); - let mut v = Vec::with_capacity(l); + let len = usize::try_from(len).unwrap(); + let mut v = Vec::with_capacity(len); // TODO(slamb): is this right?!? might have an off-by-one here. for ts in start_sec..end_sec { v.write_u16::(SUBTITLE_LENGTH as u16) @@ -1847,7 +1844,7 @@ impl FileInner { ) .expect("Vec write shouldn't fail"); } - assert_eq!(l, v.len()); + assert_eq!(len, v.len()); Ok(ARefss::new(v) .map(|v| &v[r.start as usize..r.end as usize]) .into()) @@ -2471,7 +2468,7 @@ mod tests { testutil::init(); let db = TestDb::new(RealClocks {}); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -2531,7 +2528,7 @@ mod tests { testutil::init(); let db = TestDb::new(RealClocks {}); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -2617,13 +2614,13 @@ mod tests { let db = TestDb::new(RealClocks {}); let mut encoders = Vec::new(); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); encoder.add_sample(1, 1, true, &mut r); encoder.add_sample(2, 2, false, &mut r); encoder.add_sample(3, 3, true, &mut r); encoders.push(r); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); encoder.add_sample(4, 4, true, &mut r); encoder.add_sample(5, 5, false, &mut r); encoders.push(r); @@ -2656,12 +2653,12 @@ mod tests { let db = TestDb::new(RealClocks {}); let mut encoders = Vec::new(); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); encoder.add_sample(2, 1, true, &mut r); encoder.add_sample(3, 2, false, &mut r); encoders.push(r); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); encoder.add_sample(0, 3, true, &mut r); encoders.push(r); @@ -2708,7 +2705,7 @@ mod tests { testutil::init(); let db = TestDb::new(RealClocks {}); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; @@ -2762,7 +2759,7 @@ mod tests { testutil::init(); let db = TestDb::new(RealClocks {}); let mut r = db::RecordingToInsert::default(); - let mut encoder = recording::SampleIndexEncoder::new(); + let mut encoder = recording::SampleIndexEncoder::default(); for i in 1..6 { let duration_90k = 2 * i; let bytes = 3 * i; diff --git a/server/src/slices.rs b/server/src/slices.rs index 89f32fc..97b1c73 100644 --- a/server/src/slices.rs +++ b/server/src/slices.rs @@ -129,6 +129,7 @@ where ctx: &S::Ctx, range: Range, ) -> Box> + Sync + Send> { + #[allow(clippy::suspicious_operation_groupings)] if range.start > range.end || range.end > self.len { return Box::new(stream::once(futures::future::err(wrap_error( format_err_t!( diff --git a/server/src/stream.rs b/server/src/stream.rs index 2c2d58a..eaedc06 100644 --- a/server/src/stream.rs +++ b/server/src/stream.rs @@ -5,7 +5,6 @@ use crate::h264; use cstr::cstr; use failure::{bail, Error}; -use ffmpeg; use lazy_static::lazy_static; use log::{debug, warn}; use std::convert::TryFrom; @@ -34,7 +33,7 @@ pub trait Opener: Sync { pub trait Stream { fn get_video_codecpar(&self) -> ffmpeg::avcodec::InputCodecParameters<'_>; fn get_extra_data(&self) -> Result; - fn get_next<'p>(&'p mut self) -> Result, ffmpeg::Error>; + fn get_next(&mut self) -> Result; } pub struct Ffmpeg {} @@ -166,7 +165,7 @@ impl Stream for FfmpegStream { ) } - fn get_next<'i>(&'i mut self) -> Result, ffmpeg::Error> { + fn get_next(&mut self) -> Result { loop { let p = self.input.read_frame()?; if p.stream_index() == self.video_i { diff --git a/server/src/streamer.rs b/server/src/streamer.rs index cb6146b..22a0c63 100644 --- a/server/src/streamer.rs +++ b/server/src/streamer.rs @@ -11,7 +11,6 @@ use log::{debug, info, trace, warn}; use std::result::Result; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -use time; use url::Url; pub static ROTATE_INTERVAL_SEC: i64 = 60; @@ -359,7 +358,7 @@ mod tests { fn get_frames(db: &db::LockedDatabase, id: CompositeId) -> Vec { db.with_recording_playback(id, &mut |rec| { - let mut it = recording::SampleIndexIterator::new(); + let mut it = recording::SampleIndexIterator::default(); let mut frames = Vec::new(); while it.next(&rec.video_index).unwrap() { frames.push(Frame { diff --git a/server/src/web.rs b/server/src/web.rs index 6efc69d..1cc006c 100644 --- a/server/src/web.rs +++ b/server/src/web.rs @@ -479,7 +479,7 @@ impl Service { std::time::Duration::new(30, 0), )); let mut combo = futures::stream::select( - sub_rx.map(|s| Either::Left(s)), + sub_rx.map(Either::Left), keepalive.map(|_| Either::Right(())), ); @@ -644,10 +644,10 @@ impl Service { req: Request<::hyper::Body>, ) -> Result, std::convert::Infallible> { let p = Path::decode(req.uri().path()); - let always_allow_unauthenticated = match p { - Path::NotFound | Path::Request | Path::Login | Path::Logout | Path::Static => true, - _ => false, - }; + let always_allow_unauthenticated = matches!( + p, + Path::NotFound | Path::Request | Path::Login | Path::Logout | Path::Static + ); debug!("request on: {}: {:?}", req.uri(), p); let caller = match self.authenticate(&req, always_allow_unauthenticated) { Ok(c) => c, @@ -673,10 +673,8 @@ impl Service { } } - if camera_configs { - if !caller.permissions.read_camera_configs { - bail_t!(PermissionDenied, "read_camera_configs required"); - } + if camera_configs && !caller.permissions.read_camera_configs { + bail_t!(PermissionDenied, "read_camera_configs required"); } let db = self.db.lock(); @@ -954,7 +952,7 @@ impl Service { sec: start.unix_seconds(), nsec: 0, }); - let stream_abbrev = if stream_type == db::StreamType::MAIN { + let stream_abbrev = if stream_type == db::StreamType::Main { "main" } else { "sub" @@ -1247,11 +1245,7 @@ impl Service { if let Some(sid) = extract_sid(req) { let authreq = self.authreq(req); - match self - .db - .lock() - .authenticate_session(authreq.clone(), &sid.hash()) - { + match self.db.lock().authenticate_session(authreq, &sid.hash()) { Ok((s, u)) => { return Ok(Caller { permissions: s.permissions.clone(), @@ -1319,7 +1313,7 @@ struct StaticFileRequest<'a> { impl<'a> StaticFileRequest<'a> { fn parse(path: &'a str) -> Option { - if !path.starts_with("/") || path == "/index.html" { + if !path.starts_with('/') || path == "/index.html" { return None; } @@ -1492,11 +1486,11 @@ mod tests { assert_eq!(Path::decode("/api/cameras/asdf/"), Path::NotFound); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/recordings"), - Path::StreamRecordings(cam_uuid, db::StreamType::MAIN) + Path::StreamRecordings(cam_uuid, db::StreamType::Main) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/sub/recordings"), - Path::StreamRecordings(cam_uuid, db::StreamType::SUB) + Path::StreamRecordings(cam_uuid, db::StreamType::Sub) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/junk/recordings"), @@ -1504,23 +1498,23 @@ mod tests { ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/view.mp4"), - Path::StreamViewMp4(cam_uuid, db::StreamType::MAIN, false) + Path::StreamViewMp4(cam_uuid, db::StreamType::Main, false) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/view.mp4.txt"), - Path::StreamViewMp4(cam_uuid, db::StreamType::MAIN, true) + Path::StreamViewMp4(cam_uuid, db::StreamType::Main, true) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/view.m4s"), - Path::StreamViewMp4Segment(cam_uuid, db::StreamType::MAIN, false) + Path::StreamViewMp4Segment(cam_uuid, db::StreamType::Main, false) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/view.m4s.txt"), - Path::StreamViewMp4Segment(cam_uuid, db::StreamType::MAIN, true) + Path::StreamViewMp4Segment(cam_uuid, db::StreamType::Main, true) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/live.m4s"), - Path::StreamLiveMp4Segments(cam_uuid, db::StreamType::MAIN) + Path::StreamLiveMp4Segments(cam_uuid, db::StreamType::Main) ); assert_eq!( Path::decode("/api/cameras/35144640-ff1e-4619-b0d5-4c74c185741c/main/junk"),