use super::{Driver, Error};
use async_trait::async_trait;
use std::time::Duration;

#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Default)]
/// A driver that does nothing.
pub struct NullDriver;

impl NullDriver {
	#[must_use]
	pub const fn new() -> Self {
		Self
	}
}

#[async_trait]
impl Driver for NullDriver {
	async fn get(&self, _key: &str) -> Result<Option<Vec<u8>>, Error> {
		Ok(None)
	}

	async fn has(&self, _key: &str) -> Result<bool, Error> {
		Ok(false)
	}

	async fn put(&self, _: &str, _: Vec<u8>, _: Option<Duration>) -> Result<(), Error> {
		Ok(())
	}

	async fn forget(&self, _: &str) -> Result<(), Error> {
		Ok(())
	}

	async fn flush(&self) -> Result<(), Error> {
		Ok(())
	}
}

#[cfg(test)]
mod tests {
	use super::*;
	use crate::Cache;

	#[tokio::test]
	async fn test_null_driver() {
		let cache = Cache::new(NullDriver::new());

		assert_eq!(cache.get::<String>("foo").await.unwrap(), None);
		assert!(!cache.has("foo").await.unwrap());

		cache
			.put("foo", &"bar", Duration::from_secs(1))
			.await
			.unwrap();

		assert_eq!(cache.get::<String>("foo").await.unwrap(), None);
		assert!(!cache.has("foo").await.unwrap());

		cache.forget("foo").await.unwrap();

		assert_eq!(cache.get::<String>("foo").await.unwrap(), None);
		assert!(!cache.has("foo").await.unwrap());
	}
}