about summary refs log tree commit diff stats
path: root/pkgs/by-name/mp/mpdpopm/src/ratings.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--pkgs/by-name/mp/mpdpopm/src/ratings.rs195
1 files changed, 0 insertions, 195 deletions
diff --git a/pkgs/by-name/mp/mpdpopm/src/ratings.rs b/pkgs/by-name/mp/mpdpopm/src/ratings.rs
deleted file mode 100644
index 739d3827..00000000
--- a/pkgs/by-name/mp/mpdpopm/src/ratings.rs
+++ /dev/null
@@ -1,195 +0,0 @@
-// Copyright (C) 2020-2025 Michael herstine <sp1ff@pobox.com>
-//
-// This file is part of mpdpopm.
-//
-// mpdpopm is free software: you can redistribute it and/or modify it under the terms of the GNU
-// General Public License as published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// mpdpopm is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
-// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
-// Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along with mpdpopm.  If not,
-// see <http://www.gnu.org/licenses/>.
-
-//! Logic for rating MPD tracks.
-//!
-//! # Introduction
-//!
-//! This module contains types implementing a basic rating functionality for
-//! [MPD](http://www.musicpd.org).
-//!
-//! # Discussion
-//!
-//! Rating messages to the relevant channel take the form `RATING( TRACK)?` (the two components can
-//! be separated by any whitespace). The rating can be given by an integer between 0 & 255
-//! (inclusive) represented in base ten, or as one-to-five asterisks (i.e. `\*{1,5}`). In the latter
-//! case, the rating will be mapped to 1-255 as per Winamp's
-//! [convention](http://forums.winamp.com/showpost.php?p=2903240&postcount=94):
-//!
-//!   - 224-255: 5 stars when READ with windows explorer, writes 255
-//!   - 160-223: 4 stars when READ with windows explorer, writes 196
-//!   - 096-159: 3 stars when READ with windows explorer, writes 128
-//!   - 032-095: 2 stars when READ with windows explorer, writes 64
-//!   - 001-031: 1 stars when READ with windows explorer, writes 1
-//!
-//! NB a rating of zero means "not rated".
-//!
-//! Everything after the first whitepace, if present, is taken to be the track to be rated (i.e.
-//! the track may contain whitespace). If omitted, the rating is taken to apply to the current
-//! track.
-
-use backtrace::Backtrace;
-
-use std::path::PathBuf;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-//                                             Error                                              //
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// An enumeration of ratings errors
-#[derive(Debug)]
-pub enum Error {
-    Rating {
-        source: std::num::ParseIntError,
-        text: String,
-    },
-    PlayerStopped,
-    NotImplemented {
-        feature: String,
-    },
-    BadPath {
-        pth: PathBuf,
-        back: Backtrace,
-    },
-    Client {
-        source: crate::clients::Error,
-        back: Backtrace,
-    },
-}
-
-impl std::fmt::Display for Error {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        match self {
-            Error::Rating { source, text } => write!(
-                f,
-                "Unable to interpret ``{}'' as a rating: {}",
-                text, source
-            ),
-            Error::PlayerStopped => write!(f, "Player stopped"),
-            Error::NotImplemented { feature } => write!(f, "{} not implemented", feature),
-            Error::BadPath { pth, back: _ } => write!(f, "Bad path: {:?}", pth),
-            Error::Client { source, back: _ } => write!(f, "Client error: {}", source),
-        }
-    }
-}
-
-impl std::error::Error for Error {
-    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
-        match &self {
-            Error::Rating { text: _, source } => Some(source),
-            Error::Client { source, back: _ } => Some(source),
-            _ => None,
-        }
-    }
-}
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-//                                     RatingRequest message                                      //
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
-/// The track to which a rating shall be applied.
-#[derive(Debug, PartialEq)]
-pub enum RatedTrack {
-    Current,
-    File(std::path::PathBuf),
-    Relative(i8),
-}
-
-/// A request from a client to rate a track.
-#[derive(Debug)]
-pub struct RatingRequest {
-    pub rating: u8,
-    pub track: RatedTrack,
-}
-
-/// Produce a RatingRequest instance from a line of MPD output.
-impl std::convert::TryFrom<&str> for RatingRequest {
-    type Error = Error;
-
-    /// Attempt to produce a RatingRequest instance from a line of MPD response to a
-    /// "readmessages" command. After the channel line, each subsequent line will be of the form
-    /// "message: $MESSAGE"-- this method assumes that the "message: " prefix has been stripped off
-    /// (i.e. we're dealing with a single line of text containing only our custom message format).
-    ///
-    /// For ratings, we expect a message of the form: "RATING (TRACK)?".
-    fn try_from(text: &str) -> std::result::Result<Self, Self::Error> {
-        // We expect a message of the form: "RATING (TRACK)?"; let us split `text' into those two
-        // components for separate processing:
-        let text = text.trim();
-        let (rating, track) = match text.find(char::is_whitespace) {
-            Some(idx) => (&text[..idx], &text[idx + 1..]),
-            None => (text, ""),
-        };
-
-        // Rating first-- the desired rating can be specified in a few ways...
-        let rating = if rating.is_empty() {
-            // an empty string is interpreted as zero:
-            0u8
-        } else {
-            // "*{1,5}" is interpreted as one-five stars, mapped to [0,255] as per Winamp:
-            match rating {
-                "*" => 1,
-                "**" => 64,
-                "***" => 128,
-                "****" => 196,
-                "*****" => 255,
-                // failing that, we try just interperting `rating' as an unsigned integer:
-                _ => rating.parse::<u8>().map_err(|err| Error::Rating {
-                    source: err,
-                    text: String::from(rating),
-                })?,
-            }
-        };
-
-        // Next-- track. This, too, can be given in a few ways:
-        let track = if track.is_empty() {
-            // nothing at all just means "current track"
-            RatedTrack::Current
-        } else {
-            // otherwise...
-            match text.parse::<i8>() {
-                // if we can interpret `track' as an i8, we take it as an offset...
-                Ok(i) => RatedTrack::Relative(i),
-                // else, we assume it's a path. If it's not, we'll figure that out downstream.
-                Err(_) => RatedTrack::File(std::path::PathBuf::from(&track)),
-            }
-        };
-
-        Ok(RatingRequest { rating, track })
-    }
-}
-
-#[cfg(test)]
-mod rating_request_tests {
-    use super::*;
-    use std::convert::TryFrom;
-
-    /// RatingRequest smoke tests
-    #[test]
-    fn rating_request_smoke() {
-        let req = RatingRequest::try_from("*** foo bar splat.mp3").unwrap();
-        assert_eq!(req.rating, 128);
-        assert_eq!(
-            req.track,
-            RatedTrack::File(PathBuf::from("foo bar splat.mp3"))
-        );
-        let req = RatingRequest::try_from("255").unwrap();
-        assert_eq!(req.rating, 255);
-        assert_eq!(req.track, RatedTrack::Current);
-        let _req = RatingRequest::try_from("******").unwrap_err();
-    }
-}