{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}

-- | This module exposes the underlying representation of `NameSegment`, and
--   thus should only be imported by parsers & printers.
module Unison.NameSegment.Internal (NameSegment (..)) where

import GHC.TypeLits (ErrorMessage ((:$$:)), TypeError)
import GHC.TypeLits qualified as TypeError (ErrorMessage (Text))
import Unison.Prelude
import Unison.Util.Alphabetical (Alphabetical)

-- | Represents the parts of a name between the @.@s.
newtype NameSegment = NameSegment
  { -- | Convert a name segment to unescaped text.
    --
    -- You might use this when storing a name segment as text in a database, where the literal name segment bytes are all
    -- that matter. However, you wouldn't use this to display the name segment to a user - that depends on concrete syntax.
    -- See Unison.Syntax.NameSegment (or indeed, some actual yet-built interface that abstracts concrete syntax) for that
    -- kind of function.
    --
    -- > toUnescapedText (unsafeFromText ".~") = ".~"
    NameSegment -> Text
toUnescapedText :: Text
  }
  deriving stock (NameSegment -> NameSegment -> Bool
(NameSegment -> NameSegment -> Bool)
-> (NameSegment -> NameSegment -> Bool) -> Eq NameSegment
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: NameSegment -> NameSegment -> Bool
== :: NameSegment -> NameSegment -> Bool
$c/= :: NameSegment -> NameSegment -> Bool
/= :: NameSegment -> NameSegment -> Bool
Eq, (forall x. NameSegment -> Rep NameSegment x)
-> (forall x. Rep NameSegment x -> NameSegment)
-> Generic NameSegment
forall x. Rep NameSegment x -> NameSegment
forall x. NameSegment -> Rep NameSegment x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. NameSegment -> Rep NameSegment x
from :: forall x. NameSegment -> Rep NameSegment x
$cto :: forall x. Rep NameSegment x -> NameSegment
to :: forall x. Rep NameSegment x -> NameSegment
Generic, Eq NameSegment
Eq NameSegment =>
(NameSegment -> NameSegment -> Ordering)
-> (NameSegment -> NameSegment -> Bool)
-> (NameSegment -> NameSegment -> Bool)
-> (NameSegment -> NameSegment -> Bool)
-> (NameSegment -> NameSegment -> Bool)
-> (NameSegment -> NameSegment -> NameSegment)
-> (NameSegment -> NameSegment -> NameSegment)
-> Ord NameSegment
NameSegment -> NameSegment -> Bool
NameSegment -> NameSegment -> Ordering
NameSegment -> NameSegment -> NameSegment
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: NameSegment -> NameSegment -> Ordering
compare :: NameSegment -> NameSegment -> Ordering
$c< :: NameSegment -> NameSegment -> Bool
< :: NameSegment -> NameSegment -> Bool
$c<= :: NameSegment -> NameSegment -> Bool
<= :: NameSegment -> NameSegment -> Bool
$c> :: NameSegment -> NameSegment -> Bool
> :: NameSegment -> NameSegment -> Bool
$c>= :: NameSegment -> NameSegment -> Bool
>= :: NameSegment -> NameSegment -> Bool
$cmax :: NameSegment -> NameSegment -> NameSegment
max :: NameSegment -> NameSegment -> NameSegment
$cmin :: NameSegment -> NameSegment -> NameSegment
min :: NameSegment -> NameSegment -> NameSegment
Ord, Int -> NameSegment -> ShowS
[NameSegment] -> ShowS
NameSegment -> String
(Int -> NameSegment -> ShowS)
-> (NameSegment -> String)
-> ([NameSegment] -> ShowS)
-> Show NameSegment
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> NameSegment -> ShowS
showsPrec :: Int -> NameSegment -> ShowS
$cshow :: NameSegment -> String
show :: NameSegment -> String
$cshowList :: [NameSegment] -> ShowS
showList :: [NameSegment] -> ShowS
Show)
  deriving newtype (Eq NameSegment
Eq NameSegment =>
(NameSegment -> NameSegment -> Ordering)
-> Alphabetical NameSegment
NameSegment -> NameSegment -> Ordering
forall n. Eq n => (n -> n -> Ordering) -> Alphabetical n
$ccompareAlphabetical :: NameSegment -> NameSegment -> Ordering
compareAlphabetical :: NameSegment -> NameSegment -> Ordering
Alphabetical)

instance
  ( TypeError
      ( 'TypeError.Text "You cannot implicitly convert a ‘String’ to a ‘NameSegment’. If you need a"
          ':$$: 'TypeError.Text "special-cased segment it should exist as a constant in"
          ':$$: 'TypeError.Text "“Unison.NameSegment”, otherwise it should be parsed via"
          ':$$: 'TypeError.Text "“Unison.Syntax.NameSegment”."
      )
  ) =>
  IsString NameSegment
  where
  fromString :: String -> NameSegment
fromString = String -> NameSegment
forall a. HasCallStack => a
undefined