module CodeGeneration.Utilities where

import RIO
import qualified RIO.Char as Char
import qualified RIO.Text as Text
import Types

upperCaseFirstCharacter :: Text -> Text
upperCaseFirstCharacter :: Text -> Text
upperCaseFirstCharacter Text
t =
  case Text -> Maybe (Char, Text)
Text.uncons Text
t of
    Just (Char
c, Text
rest) -> Char -> Text -> Text
Text.cons (Char -> Char
Char.toUpper Char
c) Text
rest
    Maybe (Char, Text)
Nothing -> Text
t

typeVariablesFrom :: FieldType -> Maybe [TypeVariable]
typeVariablesFrom :: FieldType -> Maybe [TypeVariable]
typeVariablesFrom (TypeVariableReferenceType TypeVariable
typeVariable) = [TypeVariable] -> Maybe [TypeVariable]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TypeVariable
typeVariable]
typeVariablesFrom (ComplexType (ArrayType Integer
_size FieldType
fieldType)) = FieldType -> Maybe [TypeVariable]
typeVariablesFrom FieldType
fieldType
typeVariablesFrom (ComplexType (SliceType FieldType
fieldType)) = FieldType -> Maybe [TypeVariable]
typeVariablesFrom FieldType
fieldType
typeVariablesFrom (ComplexType (PointerType FieldType
fieldType)) = FieldType -> Maybe [TypeVariable]
typeVariablesFrom FieldType
fieldType
typeVariablesFrom (ComplexType (OptionalType FieldType
fieldType)) = FieldType -> Maybe [TypeVariable]
typeVariablesFrom FieldType
fieldType
typeVariablesFrom (RecursiveReferenceType DefinitionName
_name) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFrom (LiteralType LiteralTypeValue
_) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFrom (BasicType BasicTypeValue
_) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFrom (DefinitionReferenceType DefinitionReference
definitionReference) =
  DefinitionReference -> Maybe [TypeVariable]
typeVariablesFromReference DefinitionReference
definitionReference

typeVariablesFromDefinition :: TypeDefinition -> Maybe [TypeVariable]
typeVariablesFromDefinition :: TypeDefinition -> Maybe [TypeVariable]
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (Struct (PlainStruct [StructField]
_))) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (Union FieldName
_tagType (PlainUnion [Constructor]
_))) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (UntaggedUnion [FieldType]
_)) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (Enumeration [EnumerationValue]
_)) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (EmbeddedUnion FieldName
_tagType [EmbeddedConstructor]
_constructors)) = Maybe [TypeVariable]
forall a. Maybe a
Nothing
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (Struct (GenericStruct [TypeVariable]
typeVariables [StructField]
_))) =
  [TypeVariable] -> Maybe [TypeVariable]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TypeVariable]
typeVariables
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (Union FieldName
_tagType (GenericUnion [TypeVariable]
typeVariables [Constructor]
_))) =
  [TypeVariable] -> Maybe [TypeVariable]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TypeVariable]
typeVariables
typeVariablesFromDefinition (TypeDefinition DefinitionName
_name (DeclaredType ModuleName
_moduleName [TypeVariable]
typeVariables)) =
  [TypeVariable] -> Maybe [TypeVariable]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [TypeVariable]
typeVariables

typeVariablesFromReference :: DefinitionReference -> Maybe [TypeVariable]
typeVariablesFromReference :: DefinitionReference -> Maybe [TypeVariable]
typeVariablesFromReference (DefinitionReference TypeDefinition
definition) = TypeDefinition -> Maybe [TypeVariable]
typeVariablesFromDefinition TypeDefinition
definition
typeVariablesFromReference (ImportedDefinitionReference ModuleName
_moduleName TypeDefinition
definition) =
  TypeDefinition -> Maybe [TypeVariable]
typeVariablesFromDefinition TypeDefinition
definition
typeVariablesFromReference (AppliedGenericReference [FieldType]
fieldTypes TypeDefinition
_definition) =
  let typeVariables :: [TypeVariable]
typeVariables = [FieldType]
fieldTypes [FieldType]
-> ([FieldType] -> [Maybe [TypeVariable]])
-> [Maybe [TypeVariable]]
forall a b. a -> (a -> b) -> b
& (FieldType -> Maybe [TypeVariable])
-> [FieldType] -> [Maybe [TypeVariable]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldType -> Maybe [TypeVariable]
typeVariablesFrom [Maybe [TypeVariable]]
-> ([Maybe [TypeVariable]] -> [[TypeVariable]]) -> [[TypeVariable]]
forall a b. a -> (a -> b) -> b
& [Maybe [TypeVariable]] -> [[TypeVariable]]
forall a. [Maybe a] -> [a]
catMaybes [[TypeVariable]]
-> ([[TypeVariable]] -> [TypeVariable]) -> [TypeVariable]
forall a b. a -> (a -> b) -> b
& [[TypeVariable]] -> [TypeVariable]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join
   in if [TypeVariable] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TypeVariable]
typeVariables then Maybe [TypeVariable]
forall a. Maybe a
Nothing else [TypeVariable] -> Maybe [TypeVariable]
forall a. a -> Maybe a
Just [TypeVariable]
typeVariables
typeVariablesFromReference
  ( AppliedImportedGenericReference
      ModuleName
_moduleName
      (AppliedTypes [FieldType]
fieldTypes)
      TypeDefinition
_definition
    ) =
    let typeVariables :: [TypeVariable]
typeVariables = [FieldType]
fieldTypes [FieldType]
-> ([FieldType] -> [Maybe [TypeVariable]])
-> [Maybe [TypeVariable]]
forall a b. a -> (a -> b) -> b
& (FieldType -> Maybe [TypeVariable])
-> [FieldType] -> [Maybe [TypeVariable]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldType -> Maybe [TypeVariable]
typeVariablesFrom [Maybe [TypeVariable]]
-> ([Maybe [TypeVariable]] -> [[TypeVariable]]) -> [[TypeVariable]]
forall a b. a -> (a -> b) -> b
& [Maybe [TypeVariable]] -> [[TypeVariable]]
forall a. [Maybe a] -> [a]
catMaybes [[TypeVariable]]
-> ([[TypeVariable]] -> [TypeVariable]) -> [TypeVariable]
forall a b. a -> (a -> b) -> b
& [[TypeVariable]] -> [TypeVariable]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join
     in if [TypeVariable] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TypeVariable]
typeVariables then Maybe [TypeVariable]
forall a. Maybe a
Nothing else [TypeVariable] -> Maybe [TypeVariable]
forall a. a -> Maybe a
Just [TypeVariable]
typeVariables
typeVariablesFromReference
  ( GenericDeclarationReference
      ModuleName
_moduleName
      DefinitionName
_definitionName
      (AppliedTypes [FieldType]
appliedTypes)
    ) =
    let typeVariables :: [TypeVariable]
typeVariables = [FieldType]
appliedTypes [FieldType]
-> ([FieldType] -> [Maybe [TypeVariable]])
-> [Maybe [TypeVariable]]
forall a b. a -> (a -> b) -> b
& (FieldType -> Maybe [TypeVariable])
-> [FieldType] -> [Maybe [TypeVariable]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldType -> Maybe [TypeVariable]
typeVariablesFrom [Maybe [TypeVariable]]
-> ([Maybe [TypeVariable]] -> [[TypeVariable]]) -> [[TypeVariable]]
forall a b. a -> (a -> b) -> b
& [Maybe [TypeVariable]] -> [[TypeVariable]]
forall a. [Maybe a] -> [a]
catMaybes [[TypeVariable]]
-> ([[TypeVariable]] -> [TypeVariable]) -> [TypeVariable]
forall a b. a -> (a -> b) -> b
& [[TypeVariable]] -> [TypeVariable]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join
     in if [TypeVariable] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TypeVariable]
typeVariables then Maybe [TypeVariable]
forall a. Maybe a
Nothing else [TypeVariable] -> Maybe [TypeVariable]
forall a. a -> Maybe a
Just [TypeVariable]
typeVariables
typeVariablesFromReference (DeclarationReference ModuleName
_moduleName DefinitionName
_definitionName) =
  Maybe [TypeVariable]
forall a. Maybe a
Nothing