1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//! This module contains the functions used only by the `unfollow_feeds` subsystem. //! //! The flow of the `unfollow_feeds` subsystem is as follows: //! //! ```plaintext //! Options::parse() //! |> ops::unfollow_feeds::verify() //! |> ops::Feed::read() //! |> ops::unfollow_feeds::print_feeds() //! |> ops::unfollow_feeds::get_feeds_to_remove() //! |> ops::Feed::write() //! ``` use self::super::super::util::prompt_any_len; use self::super::{Feed, verify_file}; use self::super::super::Error; use std::io::{BufRead, Write}; use std::path::PathBuf; /// Verify if, given the current configuration, it's permitted to continue with the subsequent steps of the `unfollow_feeds` /// subsystem. /// /// The return value contains either the path to the path to the file containing the global feeds or why getting it failed. /// /// # Examples /// /// Verifying an existing feeds file. /// /// ``` /// # use dishub::ops::unfollow_feeds; /// # use std::fs::{self, File}; /// # use std::env::temp_dir; /// # use std::io::Write; /// let tf = temp_dir().join("dishub-doctest").join("ops-unfollow_feeds-verify-0"); /// fs::create_dir_all(&tf).unwrap(); /// File::create(tf.join("feeds.toml")).unwrap().write(&[]).unwrap(); /// /// assert_eq!(unfollow_feeds::verify(&("$TEMP/ops-unfollow_feeds-verify-0".to_string(), tf.clone())), /// Ok(tf.join("feeds.toml"))); /// assert!(tf.join("feeds.toml").exists()); /// ``` /// /// Verifying a nonexistant feeds file. /// /// ``` /// # use dishub::ops::unfollow_feeds; /// # use std::env::temp_dir; /// # use dishub::Error; /// let tf = temp_dir().join("dishub-doctest").join("ops-unfollow_feeds-verify-1"); /// assert_eq!(unfollow_feeds::verify(&("$TEMP/ops-unfollow_feeds-verify-1".to_string(), tf)), /// Err(Error::RequiredFileFromSubsystemNonexistant { /// subsys: "add-feeds", /// fname: "$TEMP/ops-unfollow_feeds-verify-1/feeds.toml".to_string(), /// })); /// ``` pub fn verify(config_dir: &(String, PathBuf)) -> Result<PathBuf, Error> { verify_file("feeds.toml", true, config_dir, false, "add-feeds") } /// Print the subscribed-to feeds in a human-readable format. /// /// # Examples /// /// ``` /// # use dishub::ops::{unfollow_feeds, Feed}; /// let mut out = Vec::new(); /// unfollow_feeds::print_feeds(&[Feed::new("nabijaczleweli".to_string(), 0, 0), /// Feed::new("nabijaczleweli/dishub".to_string(), 0, 1)], /// &mut out); /// assert_eq!(&out[..], /// &b"The feeds currently subscribed to:\n\ /// \x20\x20nabijaczleweli\n\ /// \x20\x20nabijaczleweli/dishub\n\ /// \n"[..]); /// ``` pub fn print_feeds<W: Write>(feeds: &[Feed], output: &mut W) { writeln!(output, "The feeds currently subscribed to:").unwrap(); for feed in feeds { writeln!(output, " {}", feed.subject).unwrap(); } writeln!(output, "").unwrap(); } /// Prompt the user for the feed subjects to sunsubscribe from. /// /// Will accept only subjects that exist in the supplied feeds. /// /// # Examples /// /// ``` /// # use dishub::ops::{unfollow_feeds, Feed}; /// # use std::io::BufReader; /// assert_eq!(unfollow_feeds::get_feeds_to_remove( /// &[Feed::new("nabijaczleweli".to_string(), 10, 0), /// Feed::new("nabijaczleweli/dishub".to_string(), 11, 1), /// Feed::new("sehe".to_string(), 12, 2)], /// &mut BufReader::new(&b"nabijaczleweli\n\ /// nabijaczleweli/dishub\n"[..]), /// &mut Vec::new()), /// vec!["nabijaczleweli".to_string(), "nabijaczleweli/dishub".to_string()]); /// ``` pub fn get_feeds_to_remove<R: BufRead, W: Write>(feeds: &[Feed], input: &mut R, output: &mut W) -> Vec<String> { let mut selected_feeds = vec![]; while let Some(s) = prompt_any_len(input, output, "The feed to unsubscribe from (or empty to end)", |s| feeds.iter().any(|f| f.subject == *s)) .unwrap() { selected_feeds.push(s); } selected_feeds }