added the abiliy to go to next/previous page of tags with ctrl+(n/p)

This commit is contained in:
Thomas Eppers 2021-09-07 16:45:27 +02:00
parent 0d76f3b8fa
commit 17bea12b4e
3 changed files with 57 additions and 7 deletions

View File

@ -20,7 +20,9 @@ pub struct Images {
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct Tags { pub struct Tags {
#[serde(rename(deserialize = "next"))]
next_page: Option<String>, next_page: Option<String>,
#[serde(rename(deserialize = "previous"))]
prev_page: Option<String>, prev_page: Option<String>,
pub results: Vec<Images>, pub results: Vec<Images>,
} }
@ -30,6 +32,8 @@ pub enum Error {
InvalidCharacter(char), InvalidCharacter(char),
Fetching(String), Fetching(String),
Converting(String), Converting(String),
NoPrevPage,
NoNextPage,
} }
impl fmt::Display for Error { impl fmt::Display for Error {
@ -38,16 +42,22 @@ impl fmt::Display for Error {
Error::InvalidCharacter(c) => write!(f, "Invalid Character: {}", c), Error::InvalidCharacter(c) => write!(f, "Invalid Character: {}", c),
Error::Fetching(s) => write!(f, "Fetching error: {}", s), Error::Fetching(s) => write!(f, "Fetching error: {}", s),
Error::Converting(s) => write!(f, "Converting error: {}", s), Error::Converting(s) => write!(f, "Converting error: {}", s),
Error::NoNextPage => write!(f, "No next page available"),
Error::NoPrevPage => write!(f, "No previous page available"),
} }
} }
} }
impl Tags { impl Tags {
/// fetches tag information with a repository name in the form of organization/repository or library/repository in the case of official images from docker
pub fn new(repo: String) -> Result<Self, Error> { pub fn new(repo: String) -> Result<Self, Error> {
let request = format!("https://hub.docker.com/v2/repositories/{}/tags", repo); let request = format!("https://hub.docker.com/v2/repositories/{}/tags", repo);
Self::with_url(&request)
}
//get response /// fetches tag information from a url
let res = match reqwest::blocking::get(request) { fn with_url(url: &str) -> Result<Self, Error> {
let res = match reqwest::blocking::get(url) {
Ok(result) => result, Ok(result) => result,
Err(e) => return Err(Error::Fetching(format!("reqwest error: {}", e))), Err(e) => return Err(Error::Fetching(format!("reqwest error: {}", e))),
}; };
@ -76,6 +86,20 @@ impl Tags {
} }
Ok(name) Ok(name)
} }
pub fn next_page(&self) -> Result<Self, Error> {
match &self.next_page {
Some(url) => Self::with_url(url),
None => Err(Error::NoNextPage),
}
}
pub fn prev_page(&self) -> Result<Self, Error> {
match &self.prev_page {
Some(url) => Self::with_url(url),
None => Err(Error::NoPrevPage),
}
}
} }
impl fmt::Display for Images { impl fmt::Display for Images {

View File

@ -89,6 +89,12 @@ impl Ui {
} }
Ok(_) => (), Ok(_) => (),
}, },
Ok(Key::Ctrl('r')) => {
ui.repo.confirm();
ui.tags = tag_list::TagList::with_repo(ui.repo.get());
}
Ok(Key::Ctrl('n')) => ui.tags.next_page(),
Ok(Key::Ctrl('p')) => ui.tags.prev_page(),
Ok(Key::Char('\n')) => match ui.state { Ok(Key::Char('\n')) => match ui.state {
State::EditRepo => { State::EditRepo => {
ui.repo.confirm(); ui.repo.confirm();

View File

@ -7,11 +7,6 @@ use tui::widgets::{Block, Borders, List, ListState};
use crate::tags; use crate::tags;
use crate::ui::State; use crate::ui::State;
pub struct TagList {
typ: Type,
state: ListState,
}
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
NoneSelected, NoneSelected,
@ -33,6 +28,11 @@ pub enum Type {
Repo(tags::Tags), Repo(tags::Tags),
} }
pub struct TagList {
typ: Type,
state: ListState,
}
impl TagList { impl TagList {
fn new(typ: Type) -> Self { fn new(typ: Type) -> Self {
Self { Self {
@ -54,6 +54,26 @@ impl TagList {
} }
} }
pub fn next_page(&mut self) {
match &self.typ {
Type::Status(_) => (),
Type::Repo(tags) => match tags.next_page() {
Err(e) => self.typ = Type::Status(format!("{}", e)),
Ok(tags) => self.typ = Type::Repo(tags),
},
}
}
pub fn prev_page(&mut self) {
match &self.typ {
Type::Status(_) => (),
Type::Repo(tags) => match tags.prev_page() {
Err(e) => self.typ = Type::Status(format!("{}", e)),
Ok(tags) => self.typ = Type::Repo(tags),
},
}
}
/// get a list of tag names with info /// get a list of tag names with info
fn print_lines(&self) -> Vec<String> { fn print_lines(&self) -> Vec<String> {
match &self.typ { match &self.typ {