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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! Types to parse a `Computer`

use std::collections::HashMap;

use serde;
use serde_json;

use helpers::Class;

use super::monitor;

/// Helper type to act on a `Computer`
#[derive(Debug)]
pub struct ComputerName<'a>(pub &'a str);
impl<'a> From<&'a str> for ComputerName<'a> {
    fn from(v: &'a str) -> ComputerName<'a> {
        ComputerName(v)
    }
}
impl<'a> From<&'a String> for ComputerName<'a> {
    fn from(v: &'a String) -> ComputerName<'a> {
        ComputerName(v)
    }
}

/// Trait implemented by specialization of computers
pub trait Computer {}

macro_rules! computer_with_common_fields_and_impl {
    (
        $(#[$attr:meta])*
        pub struct $name:ident {
            $(
                $(#[$field_attr:meta])*
                pub $field:ident: $field_type:ty,
            )*
            $(private_fields {
                $(
                    $(#[$private_field_attr:meta])*
                    $private_field:ident: $private_field_type:ty
                ),* $(,)*
            })*
        }
    ) => {
        $(#[$attr])*
        pub struct $name {
            /// Name of the computer
            pub display_name: String,
            /// Description of the computer
            pub description: String,
            /// Icon for the computer
            pub icon: String,
            /// Icon for the computer
            pub icon_class_name: String,
            /// Is the computer idle
            pub idle: bool,
            /// Is the computer connected to master through JNLP
            pub jnlp_agent: bool,
            /// Can the computer launch a `Job`
            pub launch_supported: bool,
            /// Can a user launch a `Job` on this computer
            pub manual_launch_allowed: bool,
            /// Numbero of executors
            pub num_executors: u32,
            /// Is the computer offline
            pub offline: bool,
            /// Why is the computer offline
            pub offline_cause: Option<monitor::CommonMonitorData>,
            /// Why is the computer offline
            pub offline_cause_reason: Option<String>,
            /// Is the computer temporarily offline
            pub temporarily_offline: bool,
            /// Monitor data provided by the computer
            pub monitor_data: HashMap<String, monitor::Data>,
            /// Executors of the computer
            pub executors: Vec<Executor>,
            /// One off executors of the computer
            pub one_off_executors: Vec<Executor>,

            // TODO: actions, assignedLabels, loadStatistics 

            $(
                $(#[$field_attr])*
                pub $field: $field_type,
            )*
            $($(
                $(#[$private_field_attr])*
                $private_field: $private_field_type,
            )*)*
        }
        impl Computer for $name {}
    };
}

computer_with_common_fields_and_impl!(/// A Jenkins `Computer`
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CommonComputer {
    /// _class provided by Jenkins
    #[serde(rename = "_class")]
    pub class: Option<String>,
    private_fields {
        #[serde(flatten)]
        other_fields: serde_json::Value,
    }
});
specialize!(CommonComputer => Computer);

computer_with_common_fields_and_impl!(/// The master computer
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct MasterComputer {});
register_class!("hudson.model.Hudson$MasterComputer" => MasterComputer);

computer_with_common_fields_and_impl!(/// A slave computer
#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct SlaveComputer {});
register_class!("hudson.slave.SlaveComputer" => SlaveComputer);

/// An `Executor` of a `Computer`
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(untagged)]
pub enum Executor {
    /// An `Executor` of a `Computer`
    #[serde(rename_all = "camelCase")]
    Executor {
        /// `Build` that is currently running. Will be None if the executor
        /// is idle, or if it is building a job the current user doesn't have
        /// permissions to see
        current_executable: Option<::build::ShortBuild>,
        /// Is it likely stuck
        likely_stuck: bool,
        /// Executor number
        number: u32,
        /// Progress in current executable
        progress: ExecutorProgress,
    },
    /// No data was retrieved about current executor, probably due to not
    /// enough depth in request
    MissingData {},
}

/// Progress in an executable
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(untagged)]
pub enum ExecutorProgress {
    /// Percent done
    Percent(u32),
    /// Nothing
    None(i32),
}