content: module Data.Schematic.Path where
  
  import Data.Foldable as F
  import Data.Singletons.Prelude
  import Data.Singletons.TypeLits
  import Data.Text as T
  import Data.Aeson.Internal
  
  
  newtype JSONPathText = JSONPathText Text
    deriving (Show)
  
  data PathSegment = PathKey Symbol | PathIx Nat
  
  data instance Sing (jp :: PathSegment) where
    SKey :: (SingI k) => Sing (k :: Symbol) -> Sing ('PathKey k)
    SIx :: (SingI n) => Sing (n :: Nat) -> Sing ('PathIx n)
  
  demotePath :: Sing (ps :: [PathSegment]) -> JSONPath
  demotePath = go []
    where
      go :: JSONPath -> Sing (ps :: [PathSegment]) -> JSONPath
      go acc SNil = acc
      go acc (SCons p ps) = go (acc ++ [demotePathSeg p]) ps
      demotePathSeg :: Sing (ps :: PathSegment) -> JSONPathElement
      demotePathSeg (SKey s) = Key $ T.pack $ withKnownSymbol s $ symbolVal s
      demotePathSeg (SIx n) = Index $ withKnownNat n $ fromIntegral $ natVal n
  
  demotedPathToText :: JSONPath -> JSONPathText
  demotedPathToText = JSONPathText . F.foldl' renderPathSegment ""
    where
      renderPathSegment acc (Key t) = acc <> "." <> t
      renderPathSegment acc (Index n)  = acc <> "[" <> T.pack (show n) <> "]"
  
  pathToText :: Sing (ps :: [PathSegment]) -> JSONPathText
  pathToText = demotedPathToText . demotePath
  