z_osmf 0.13.5

The Rust z/OSMF Client
Documentation
use std::marker::PhantomData;
use std::sync::Arc;

use serde::{Deserialize, Serialize};
use z_osmf_macros::{Endpoint, Getters};

use crate::convert::TryFromResponse;
use crate::{ClientCore, Result};

#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum SystemId {
    #[default]
    Local,
    Named {
        sysplex: String,
        system: String,
    },
}

impl SystemId {
    pub fn new() -> Self {
        SystemId::default()
    }

    pub fn named<X, S>(sysplex: X, system: S) -> Self
    where
        X: std::fmt::Display,
        S: std::fmt::Display,
    {
        let sysplex = sysplex.to_string();
        let system = system.to_string();

        SystemId::Named { sysplex, system }
    }
}

impl std::fmt::Display for SystemId {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            SystemId::Local => write!(f, "local"),
            SystemId::Named { sysplex, system } => write!(f, "{}.{}", sysplex, system),
        }
    }
}

#[derive(Clone, Debug, Deserialize, Eq, Getters, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct SystemVariable {
    name: Arc<str>,
    value: Arc<str>,
    description: Option<Arc<str>>,
}

#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub struct SystemVariableList {
    inner: Arc<[SystemVariable]>,
}

impl TryFromResponse for SystemVariableList {
    async fn try_from_response(value: reqwest::Response) -> Result<Self> {
        let ResponseJson { variables } = value.json().await?;

        Ok(SystemVariableList { inner: variables })
    }
}

impl std::ops::Deref for SystemVariableList {
    type Target = [SystemVariable];

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

#[derive(Clone, Debug, Endpoint)]
#[endpoint(method = get, path = "/zosmf/variables/rest/1.0/systems/{system_id}")]
pub struct SystemVariableListBuilder<T>
where
    T: TryFromResponse,
{
    core: Arc<ClientCore>,

    #[endpoint(path, builder_fn = build_system_id)]
    system_id: Option<SystemId>,
    #[endpoint(skip_setter, builder_fn = build_names)]
    names: Option<Vec<Arc<str>>>,

    target_type: PhantomData<T>,
}

impl<T> SystemVariableListBuilder<T>
where
    T: TryFromResponse,
{
    pub fn name<V>(self, value: V) -> Self
    where
        V: std::fmt::Display,
    {
        let mut new = self;
        match new.names {
            Some(ref mut names) => names.push(value.to_string().into()),
            None => new.names = Some(vec![value.to_string().into()]),
        }

        new
    }

    pub fn names<V>(self, value: &[V]) -> Self
    where
        V: std::fmt::Display,
    {
        let mut new = self;
        match new.names {
            Some(ref mut names) => names.extend(value.iter().map(|v| v.to_string().into())),
            None => new.names = Some(value.iter().map(|v| v.to_string().into()).collect()),
        }

        new
    }
}

#[derive(Deserialize)]
struct ResponseJson {
    #[serde(rename = "system-variable-list")]
    variables: Arc<[SystemVariable]>,
}

fn build_names<T>(
    request_builder: reqwest::RequestBuilder,
    builder: &SystemVariableListBuilder<T>,
) -> reqwest::RequestBuilder
where
    T: TryFromResponse,
{
    let query: Arc<[_]> = builder
        .names
        .iter()
        .map(|name| ("var-name", name))
        .collect();

    request_builder.query(&query)
}

fn build_system_id<T>(builder: &SystemVariableListBuilder<T>) -> &SystemId
where
    T: TryFromResponse,
{
    builder.system_id.as_ref().unwrap_or(&SystemId::Local)
}