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)]
pub struct Tags {
#[serde(rename(deserialize = "next"))]
next_page: Option<String>,
#[serde(rename(deserialize = "previous"))]
prev_page: Option<String>,
pub results: Vec<Images>,
}
@ -30,6 +32,8 @@ pub enum Error {
InvalidCharacter(char),
Fetching(String),
Converting(String),
NoPrevPage,
NoNextPage,
}
impl fmt::Display for Error {
@ -38,16 +42,22 @@ impl fmt::Display for Error {
Error::InvalidCharacter(c) => write!(f, "Invalid Character: {}", c),
Error::Fetching(s) => write!(f, "Fetching 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 {
/// 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> {
let request = format!("https://hub.docker.com/v2/repositories/{}/tags", repo);
Self::with_url(&request)
}
//get response
let res = match reqwest::blocking::get(request) {
/// fetches tag information from a url
fn with_url(url: &str) -> Result<Self, Error> {
let res = match reqwest::blocking::get(url) {
Ok(result) => result,
Err(e) => return Err(Error::Fetching(format!("reqwest error: {}", e))),
};
@ -76,6 +86,20 @@ impl Tags {
}
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 {

View File

@ -89,6 +89,12 @@ impl Ui {
}
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 {
State::EditRepo => {
ui.repo.confirm();

View File

@ -7,11 +7,6 @@ use tui::widgets::{Block, Borders, List, ListState};
use crate::tags;
use crate::ui::State;
pub struct TagList {
typ: Type,
state: ListState,
}
#[derive(Debug)]
pub enum Error {
NoneSelected,
@ -33,6 +28,11 @@ pub enum Type {
Repo(tags::Tags),
}
pub struct TagList {
typ: Type,
state: ListState,
}
impl TagList {
fn new(typ: Type) -> 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
fn print_lines(&self) -> Vec<String> {
match &self.typ {