farmsim 0.1.0

Bindings/API schemas for all compatible Farming Simulator titles
Documentation
pub mod careersavegame;
pub mod stats;

use std::{
  borrow::Cow,
  fmt
};

/// This is only effective on DSS field in [Endpoint] struct
#[derive(Debug, Clone, Copy)]
pub enum Format {
  Json,
  Xml
}

impl fmt::Display for Format {
  fn fmt(
    &self,
    f: &mut fmt::Formatter<'_>
  ) -> fmt::Result {
    let ext = match self {
      Self::Json => "json",
      Self::Xml => "xml"
    };
    write!(f, "{ext}")
  }
}

/// List of supported filenames in the `dedicated-server-savegame` endpoint
#[derive(Debug, Clone, Copy)]
pub enum Filename {
  CareerSavegame,
  Vehicles,
  Economy
}

impl fmt::Display for Filename {
  fn fmt(
    &self,
    f: &mut fmt::Formatter<'_>
  ) -> fmt::Result {
    let file = match self {
      Self::CareerSavegame => "careerSavegame",
      Self::Vehicles => "vehicles",
      Self::Economy => "economy"
    };
    write!(f, "{file}")
  }
}

pub struct EndpointBuilder {
  /// Either `example.com` or `1.2.3.4`
  ip:     Cow<'static, str>,
  /// This is your API code found on the webinterface's settings page<br>
  /// Something like `?code=<your API code>` in the URL(s)
  code:   Cow<'static, str>,
  /// Only effective on DSS field in [Endpoint] struct
  format: Format
}

impl EndpointBuilder {
  pub fn new(
    ip: &str,
    code: &str
  ) -> Self {
    // todo; use proper pattern matching to cover possible edge cases
    let ip = ip.strip_prefix("http://").expect("failed to strip http protocol");

    Self {
      ip:     Cow::Owned(ip.into()),
      code:   Cow::Owned(code.into()),
      format: Format::Json
    }
  }

  /// Sets the data format type for dedicated-server-stats (DSS) endpoint
  pub fn format(
    mut self,
    format: Format
  ) -> Self {
    self.format = format;
    self
  }

  pub fn build(self) -> Endpoint { Endpoint::new(self.ip, self.code, self.format) }
}

pub struct Endpoint {
  base_url: Cow<'static, str>,
  code:     Cow<'static, str>,
  format:   Format
}

impl Endpoint {
  fn new(
    ip: Cow<'static, str>,
    code: Cow<'static, str>,
    format: Format
  ) -> Self {
    Self {
      base_url: Cow::Owned(format!("http://{ip}/feed")),
      code,
      format
    }
  }

  /// Returns the string containing the `/feed/dedicated-server-stats` endpoint
  pub fn stats(&self) -> String { format!("{}/dedicated-server-stats.{}?code={}", self.base_url, self.format, self.code) }

  /// Returns the string containing the `/feed/dedicated-server-savegame` endpoint with chosen filename
  pub fn savegame(
    &self,
    filename: Filename
  ) -> String {
    format!("{}/dedicated-server-savegame.html?code={}&file={filename}", self.base_url, self.code)
  }
}