use std::hash::Hash;
use sqlx::Postgres;
use crate::stable_hash;
pub type Singleton = GenericSingleton<bool>;
pub struct GenericSingleton<T: Default>(T);
impl<T: Default> core::fmt::Debug for GenericSingleton<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Singleton").finish()
}
}
impl<T: Clone + Default> Clone for GenericSingleton<T> {
fn clone(&self) -> Self {
Self::default()
}
}
impl<T: Default> PartialEq for GenericSingleton<T> {
fn eq(&self, _other: &Self) -> bool {
true
}
}
impl<T: Default> Eq for GenericSingleton<T> {}
impl<T: Default> Hash for GenericSingleton<T> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
0_u8.hash(state)
}
}
impl<T: Default> PartialOrd for GenericSingleton<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(&other))
}
}
impl<T: Default> Ord for GenericSingleton<T> {
fn cmp(&self, _other: &Self) -> std::cmp::Ordering {
std::cmp::Ordering::Equal
}
}
impl<T: Default> Default for GenericSingleton<T> {
fn default() -> Self {
Self(T::default())
}
}
impl<'r, T: Default + sqlx::Decode<'r, Postgres>> sqlx::Decode<'r, Postgres>
for GenericSingleton<T>
{
fn decode(
value: <Postgres as sqlx::Database>::ValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
T::decode(value).map(Self)
}
}
impl<'q, T: Default + sqlx::Encode<'q, Postgres>> sqlx::Encode<'q, Postgres>
for GenericSingleton<T>
{
fn encode_by_ref(
&self,
buf: &mut <Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
self.0.encode_by_ref(buf)
}
fn encode(
self,
buf: &mut <Postgres as sqlx::Database>::ArgumentBuffer<'q>,
) -> Result<sqlx::encode::IsNull, Box<dyn std::error::Error + Send + Sync>> {
self.0.encode(buf)
}
fn produces(&self) -> Option<<Postgres as sqlx::Database>::TypeInfo> {
self.0.produces()
}
fn size_hint(&self) -> usize {
self.0.size_hint()
}
}
impl<T: Default + sqlx::Type<Postgres>> sqlx::Type<Postgres> for GenericSingleton<T> {
fn type_info() -> <Postgres as sqlx::Database>::TypeInfo {
<T>::type_info()
}
fn compatible(ty: &<Postgres as sqlx::Database>::TypeInfo) -> bool {
<T>::compatible(ty)
}
}
impl<T: Default + sqlx::postgres::PgHasArrayType> sqlx::postgres::PgHasArrayType
for GenericSingleton<T>
{
fn array_type_info() -> sqlx::postgres::PgTypeInfo {
T::array_type_info()
}
}
impl<T: Default + async_graphql::InputType> async_graphql::InputType for GenericSingleton<T> {
type RawValueType = T::RawValueType;
fn type_name() -> std::borrow::Cow<'static, str> {
T::type_name()
}
fn create_type_info(registry: &mut async_graphql::registry::Registry) -> String {
T::create_type_info(registry)
}
fn parse(value: Option<async_graphql::Value>) -> async_graphql::InputValueResult<Self> {
T::parse(value)
.map(|_| Self::default())
.map_err(async_graphql::InputValueError::propagate)
}
fn to_value(&self) -> async_graphql::Value {
self.0.to_value()
}
fn as_raw_value(&self) -> Option<&Self::RawValueType> {
self.0.as_raw_value()
}
fn qualified_type_name() -> String {
T::qualified_type_name()
}
}
impl<T: Default + async_graphql::ScalarType + async_graphql::InputType> async_graphql::ScalarType
for GenericSingleton<T>
{
fn parse(value: async_graphql::Value) -> async_graphql::InputValueResult<Self> {
<T as async_graphql::ScalarType>::parse(value)
.map(|_| Self::default())
.map_err(|e| async_graphql::InputValueError::propagate(e))
}
fn to_value(&self) -> async_graphql::Value {
async_graphql::ScalarType::to_value(&self.0)
}
}
impl<T: Default + async_graphql::OutputType> async_graphql::OutputType for GenericSingleton<T> {
fn type_name() -> std::borrow::Cow<'static, str> {
T::type_name()
}
fn qualified_type_name() -> String {
T::qualified_type_name()
}
fn introspection_type_name(&self) -> std::borrow::Cow<'static, str> {
self.0.introspection_type_name()
}
fn create_type_info(registry: &mut async_graphql::registry::Registry) -> String {
T::create_type_info(registry)
}
async fn resolve(
&self,
ctx: &async_graphql::ContextSelectionSet<'_>,
field: &async_graphql::Positioned<async_graphql::parser::types::Field>,
) -> async_graphql::ServerResult<async_graphql::Value> {
self.0.resolve(ctx, field).await
}
}
impl<T: Default> stable_hash::StableHash for GenericSingleton<T> {
fn stable_hash<H: stable_hash::StableHasher>(&self, field_address: H::Addr, state: &mut H) {
use stable_hash::FieldAddress;
0_i32.stable_hash(field_address.child(0), state);
}
}
impl<T: Default + crate::__internal::ToDbFilter> crate::__internal::ToDbFilter
for GenericSingleton<T>
{
type Filter = T::Filter;
fn to_db_filter(self) -> Self::Filter {
self.0.to_db_filter()
}
}
impl<T: Default + crate::__internal::ToGraphqlFilter> crate::__internal::ToGraphqlFilter
for GenericSingleton<T>
{
type Filter = T::Filter;
fn to_graphql_filter(self) -> Self::Filter {
self.0.to_graphql_filter()
}
}
impl<T: Default + crate::poi::Hashable> crate::poi::Hashable for GenericSingleton<T> {
fn variant() -> crate::poi::ValueVariant {
T::variant()
}
}