Skip to content

Commit

Permalink
[PLATFORM-1580]: Retire 0.7.0 and fix configuration mixup (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpiemontese authored Mar 6, 2024
1 parent 5b0b6a2 commit e4fbfe2
Show file tree
Hide file tree
Showing 12 changed files with 349 additions and 426 deletions.
21 changes: 19 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [0.7.1] - 2024-03-05

### Added

- Implemented `From<Configuration>` for `dogstatsd::Options`

### Changed

- `Config` is now `Configuration`

### Removed

- The `Configuration` trait
- `Country` and `Environment` serialization

---

## [0.7.0] - 2024-03-04

### Changed
Expand Down Expand Up @@ -111,8 +128,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.1.5]


[Unreleased]: https://github.com/primait/prima_datadog.rs/compare/0.7.0...HEAD
[Unreleased]: https://github.com/primait/prima_datadog.rs/compare/0.7.1...HEAD
[0.7.1]: https://github.com/primait/prima_datadog.rs/compare/0.7.0...0.7.1
[0.7.0]: https://github.com/primait/prima_datadog.rs/compare/0.7.0...0.7.0
[0.6.0]: https://github.com/primait/prima_datadog.rs/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/primait/prima_datadog.rs/compare/0.4.0...0.5.0
Expand Down
12 changes: 8 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,26 @@ description = "An opinionated library to share code and approach to Datadog logg
edition = "2018"
license = "MIT"
name = "prima_datadog"
version = "0.7.0"
version = "0.7.1"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = []

serde = ["dep:serde"]

[dependencies]
async-trait = "0.1"
dogstatsd = {version = "=0.11.0", default-features = false}
once_cell = {version = "1.9", default-features = false, features = ["std"]}
serde = {version = "1", optional = true}
thiserror = {version = "1.0", default-features = false}

# Optional
serde = {version = "1", optional = true}

[dev-dependencies]
criterion = "0.5"
mockall = {version = "0.12", default-features = false}
rand = "0.8.5"
serde_json = "1"
serial_test = {version = "3.0.0", default-features = false}

[[bench]]
Expand Down
5 changes: 3 additions & 2 deletions benches/basic_incr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, Criterion};
use prima_datadog::{
configuration::{Config, Country},
configuration::{Configuration, Country, Environment},
Datadog, TagTrackerConfiguration,
};

Expand All @@ -9,8 +9,9 @@ fn setup(_: &mut Criterion) {
let tracker_config = TagTrackerConfiguration::new()
.with_threshold(21)
.with_custom_action(|_, _, _| {});
let configuration = Config::new("0.0.0.0:1234", "prima_datadog_benchmarks")
let configuration = Configuration::new("0.0.0.0:1234", "prima_datadog_benchmarks")
.with_country(Country::It)
.with_environment(Environment::Dev)
.with_tracker_configuration(tracker_config);
Datadog::init(configuration).unwrap();
}
Expand Down
95 changes: 95 additions & 0 deletions src/configuration/country.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use std::{fmt::Display, str::FromStr};

use crate::error::Error;

/// Represents the country in which the datadog client runs.
/// This is useful for enforcing rules based on country for every application that uses the library.
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Country {
Common,
It,
Es,
Uk,
}

impl Country {
/// Returns the string representation of the country.
pub fn as_str(&self) -> &'static str {
match self {
Country::Common => "common",
Country::It => "it",
Country::Es => "es",
Country::Uk => "uk",
}
}
}

impl FromStr for Country {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"common" => Ok(Self::Common),
"it" => Ok(Self::It),
"es" => Ok(Self::Es),
"uk" => Ok(Self::Uk),
_ => Err(Error::WrongCountryDefinition),
}
}
}

impl Display for Country {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}

#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Country {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct CountryVisitor;
impl<'de> serde::de::Visitor<'de> for CountryVisitor {
type Value = Country;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a country tag")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Country::from_str(v).map_err(|_| E::custom("unknown country tag"))
}
}
deserializer.deserialize_str(CountryVisitor)
}
}

#[cfg(test)]
mod tests {
use crate::configuration::Configuration;

use super::*;

#[test]
pub fn test_country() {
let config = Configuration::new("to_addr", "namespace")
.with_from_addr("from_addr")
.with_country(Country::It);

assert_eq!(config.default_tags(), vec!["prima:country:it"]);

let config = Configuration::new("to_addr", "namespace")
.with_from_addr("from_addr")
.with_country(Country::It)
.with_country(Country::Es);

// Datadog tag keys are allowed to map to multiple values, and I suppose we're ok with that too (e.g. cross-country infra down the line?)
assert_eq!(config.default_tags(), vec!["prima:country:it", "prima:country:es"]);
}
}
97 changes: 97 additions & 0 deletions src/configuration/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use std::str::FromStr;

use crate::error::Error;

/// Represent an environment in which the datadog client runs.
/// This is useful for enforcing rules based on environment for every application that uses the library.
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum Environment {
Dev,
Staging,
Production,
}

impl Environment {
/// Returns the string representation of the environment.
pub fn as_str(&self) -> &'static str {
match self {
Environment::Dev => "dev",
Environment::Staging => "staging",
Environment::Production => "production",
}
}
}

impl FromStr for Environment {
type Err = Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"dev" => Ok(Self::Dev),
"staging" => Ok(Self::Staging),
"production" => Ok(Self::Production),
_ => Err(Error::WrongEnvironmentDefinition),
}
}
}

impl std::fmt::Display for Environment {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}

#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Environment {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct EnvironmentVisitor;
impl<'de> serde::de::Visitor<'de> for EnvironmentVisitor {
type Value = Environment;

fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a environment tag")
}

fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Environment::from_str(v).map_err(|_| E::custom("unknown environment tag"))
}
}
deserializer.deserialize_str(EnvironmentVisitor)
}
}

#[cfg(test)]
mod tests {
use crate::configuration::Configuration;

use super::*;

#[test]
pub fn test_from_str() {
assert_eq!(Some(Environment::Dev), "dev".parse().ok());
assert_eq!(Some(Environment::Staging), "staging".parse().ok());
assert_eq!(Some(Environment::Production), "production".parse().ok());
}

#[test]
pub fn test_from_str_err() {
//assert_eq!(None, "".parse::<Environment>().err());
assert_eq!(None, "whatever".parse::<Environment>().ok());
}

#[test]
pub fn test_environment() {
let config = Configuration::new("to_addr", "namespace")
.with_from_addr("from_addr")
.with_environment(Environment::Dev);

assert_eq!(config.default_tags(), vec!["env:dev"]);
}
}
Loading

0 comments on commit e4fbfe2

Please sign in to comment.