use std::fs::File;
use std::io::Read;
use crate::error::DatafileError;
use error_stack::{Report, Result, ResultExt};
use std::ops::Deref;
pub(crate) use attribute::{Attribute, AttributeMap};
use audience::AudienceMap;
use environment::Environment;
#[cfg(feature = "online")]
pub(crate) use event::{Event, EventMap};
pub(crate) use experiment::{Experiment, ExperimentMap};
pub(crate) use feature_flag::{FeatureFlag, FeatureFlagMap};
use revision::Revision;
use rollout::RolloutMap;
use traffic_allocation::TrafficAllocation;
pub(crate) use variation::{Variation, VariationMap};
mod attribute;
mod audience;
mod environment;
#[cfg(feature = "online")]
mod event;
mod experiment;
mod feature_flag;
mod revision;
mod rollout;
mod traffic_allocation;
mod variation;
#[derive(Debug)]
pub struct Datafile(Environment);
impl Datafile {
#[cfg(feature = "online")]
pub fn from_sdk_key(sdk_key: &str) -> Result<Datafile, DatafileError> {
let url = format!("https://cdn.optimizely.com/datafiles/{}.json", sdk_key);
let response = ureq::get(&url)
.call()
.change_context(DatafileError::FailedRequest)?;
let content = response
.into_string()
.change_context(DatafileError::FailedResponse)?;
Datafile::from_string(content)
}
pub fn from_local_datafile(file_path: &str) -> Result<Datafile, DatafileError> {
let mut content = String::new();
let mut file = File::open(file_path).change_context(DatafileError::FailedFileOpen)?;
file.read_to_string(&mut content)
.change_context(DatafileError::FailedFileRead)?;
Datafile::from_string(content)
}
pub fn from_string<S>(content: S) -> Result<Datafile, DatafileError>
where
S: AsRef<str>,
{
Datafile::try_from(content.as_ref())
}
}
impl TryFrom<&str> for Datafile {
type Error = Report<DatafileError>;
fn try_from(value: &str) -> std::result::Result<Self, Self::Error> {
let environment = serde_json::from_str(value).change_context(DatafileError::InvalidJson)?;
Ok(Datafile(environment))
}
}
impl Deref for Datafile {
type Target = Environment;
fn deref(&self) -> &Self::Target {
&self.0
}
}