use failure::Error;
use serde;
use serde_json;
use helpers::Class;
use client;
use client_internals::{Name, Path};
use job::{JobName, ShortJob};
use property::CommonProperty;
use Jenkins;
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ShortView {
pub name: String,
pub url: String,
#[serde(flatten)]
other_fields: Option<serde_json::Value>,
}
impl ShortView {
pub fn get_full_view(&self, jenkins_client: &Jenkins) -> Result<CommonView, Error> {
let path = jenkins_client.url_to_path(&self.url);
if let Path::View { .. } = path {
Ok(jenkins_client.get(&path)?.json()?)
} else {
Err(client::Error::InvalidUrl {
url: self.url.clone(),
expected: client::error::ExpectedType::View,
}.into())
}
}
}
#[derive(Debug)]
pub struct ViewName<'a>(pub &'a str);
impl<'a> From<&'a str> for ViewName<'a> {
fn from(v: &'a str) -> ViewName<'a> {
ViewName(v)
}
}
impl<'a> From<&'a String> for ViewName<'a> {
fn from(v: &'a String) -> ViewName<'a> {
ViewName(v)
}
}
impl<'a> From<&'a ShortView> for ViewName<'a> {
fn from(v: &'a ShortView) -> ViewName<'a> {
ViewName(&v.name)
}
}
impl<'a, T: View> From<&'a T> for ViewName<'a> {
fn from(v: &'a T) -> ViewName<'a> {
ViewName(v.name())
}
}
pub trait View {
fn name(&self) -> &str;
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CommonView {
#[serde(rename = "_class")]
pub class: Option<String>,
pub description: Option<String>,
pub name: String,
pub url: String,
pub jobs: Vec<ShortJob>,
pub property: Vec<CommonProperty>,
#[serde(flatten)]
other_fields: serde_json::Value,
}
specialize!(CommonView => View);
impl View for CommonView {
fn name(&self) -> &str {
&self.name
}
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct ListView {
pub description: Option<String>,
pub name: String,
pub url: String,
pub jobs: Vec<ShortJob>,
pub property: Vec<CommonProperty>,
}
register_class!("hudson.model.ListView" => ListView);
impl View for ListView {
fn name(&self) -> &str {
&self.name
}
}
impl ListView {
pub fn add_job<'a, J>(&self, jenkins_client: &Jenkins, job_name: J) -> Result<(), Error>
where
J: Into<JobName<'a>>,
{
let path = jenkins_client.url_to_path(&self.url);
if let Path::View { name } = path {
let _ = jenkins_client.post(&Path::AddJobToView {
job_name: Name::Name(&job_name.into().0),
view_name: name,
})?;
Ok(())
} else {
Err(client::Error::InvalidUrl {
url: self.url.clone(),
expected: client::error::ExpectedType::View,
}.into())
}
}
pub fn remove_job<'a, J>(&self, jenkins_client: &Jenkins, job_name: J) -> Result<(), Error>
where
J: Into<JobName<'a>>,
{
let path = jenkins_client.url_to_path(&self.url);
if let Path::View { name } = path {
let _ = jenkins_client.post(&Path::RemoveJobFromView {
job_name: Name::Name(&job_name.into().0),
view_name: name,
})?;
Ok(())
} else {
Err(client::Error::InvalidUrl {
url: self.url.clone(),
expected: client::error::ExpectedType::View,
}.into())
}
}
}
impl Jenkins {
pub fn get_view<'a, V>(&self, view_name: V) -> Result<CommonView, Error>
where
V: Into<ViewName<'a>>,
{
Ok(self.get(&Path::View {
name: Name::Name(&view_name.into().0),
})?
.json()?)
}
pub fn add_job_to_view<'a, 'b, V, J>(&self, view_name: V, job_name: J) -> Result<(), Error>
where
V: Into<ViewName<'a>>,
J: Into<JobName<'a>>,
{
let _ = self.post(&Path::AddJobToView {
job_name: Name::Name(&job_name.into().0),
view_name: Name::Name(&view_name.into().0),
})?;
Ok(())
}
pub fn remove_job_from_view<'a, 'b, V, J>(&self, view_name: V, job_name: J) -> Result<(), Error>
where
V: Into<ViewName<'a>>,
J: Into<JobName<'a>>,
{
let _ = self.post(&Path::AddJobToView {
job_name: Name::Name(&job_name.into().0),
view_name: Name::Name(&view_name.into().0),
})?;
Ok(())
}
}