module Unison.Syntax.NamePrinter where

import Data.Text qualified as Text
import Unison.HashQualified qualified as HQ
import Unison.HashQualifiedPrime qualified as HQ'
import Unison.LabeledDependency (LabeledDependency)
import Unison.LabeledDependency qualified as LD
import Unison.Name (Name)
import Unison.Prelude
import Unison.Reference (Reference)
import Unison.Referent (Referent)
import Unison.ShortHash (ShortHash)
import Unison.ShortHash qualified as SH
import Unison.Syntax.HashQualified qualified as HQ (toText)
import Unison.Syntax.Name qualified as Name (toText)
import Unison.Util.Pretty (Pretty)
import Unison.Util.Pretty qualified as PP
import Unison.Util.SyntaxText qualified as S

type SyntaxText = S.SyntaxText' Reference

prettyName :: (IsString s) => Name -> Pretty s
prettyName :: forall s. IsString s => Name -> Pretty s
prettyName = Text -> Pretty s
forall s. IsString s => Text -> Pretty s
PP.text (Text -> Pretty s) -> (Name -> Text) -> Name -> Pretty s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Text
Name.toText

prettyHashQualified :: HQ.HashQualified Name -> Pretty SyntaxText
prettyHashQualified :: HashQualified Name -> Pretty SyntaxText
prettyHashQualified HashQualified Name
hq = (Pretty SyntaxText -> Pretty SyntaxText)
-> (Pretty SyntaxText -> Pretty SyntaxText)
-> HashQualified Name
-> Pretty SyntaxText
forall s.
IsString s =>
(Pretty s -> Pretty s)
-> (Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
styleHashQualified' Pretty SyntaxText -> Pretty SyntaxText
forall a. a -> a
id (Element Reference -> Pretty SyntaxText -> Pretty SyntaxText
forall r.
Element r -> Pretty (SyntaxText' r) -> Pretty (SyntaxText' r)
fmt (Element Reference -> Pretty SyntaxText -> Pretty SyntaxText)
-> Element Reference -> Pretty SyntaxText -> Pretty SyntaxText
forall a b. (a -> b) -> a -> b
$ HashQualified Name -> Element Reference
forall r. HashQualified Name -> Element r
S.HashQualifier HashQualified Name
hq) HashQualified Name
hq

prettyHashQualified' :: HQ'.HashQualified Name -> Pretty SyntaxText
prettyHashQualified' :: HashQualified Name -> Pretty SyntaxText
prettyHashQualified' = HashQualified Name -> Pretty SyntaxText
prettyHashQualified (HashQualified Name -> Pretty SyntaxText)
-> (HashQualified Name -> HashQualified Name)
-> HashQualified Name
-> Pretty SyntaxText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashQualified Name -> HashQualified Name
forall n. HashQualified n -> HashQualified n
HQ'.toHQ

prettyHashQualified0 :: (IsString s) => HQ.HashQualified Name -> Pretty s
prettyHashQualified0 :: forall s. IsString s => HashQualified Name -> Pretty s
prettyHashQualified0 = Text -> Pretty s
forall s. IsString s => Text -> Pretty s
PP.text (Text -> Pretty s)
-> (HashQualified Name -> Text) -> HashQualified Name -> Pretty s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HashQualified Name -> Text
HQ.toText

-- | Pretty-print a reference as a name and the given number of characters of
-- its hash.
prettyNamedReference :: Int -> Name -> Reference -> Pretty SyntaxText
prettyNamedReference :: Int -> Name -> Reference -> Pretty SyntaxText
prettyNamedReference Int
len Name
name =
  HashQualified Name -> Pretty SyntaxText
prettyHashQualified (HashQualified Name -> Pretty SyntaxText)
-> (Reference -> HashQualified Name)
-> Reference
-> Pretty SyntaxText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> HashQualified Name -> HashQualified Name
forall n. Int -> HashQualified n -> HashQualified n
HQ.take Int
len (HashQualified Name -> HashQualified Name)
-> (Reference -> HashQualified Name)
-> Reference
-> HashQualified Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Reference -> HashQualified Name
forall n. n -> Reference -> HashQualified n
HQ.fromNamedReference Name
name

-- | Pretty-print a referent as a name and the given number of characters of its
-- hash.
prettyNamedReferent :: Int -> Name -> Referent -> Pretty SyntaxText
prettyNamedReferent :: Int -> Name -> Referent -> Pretty SyntaxText
prettyNamedReferent Int
len Name
name =
  HashQualified Name -> Pretty SyntaxText
prettyHashQualified (HashQualified Name -> Pretty SyntaxText)
-> (Referent -> HashQualified Name)
-> Referent
-> Pretty SyntaxText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> HashQualified Name -> HashQualified Name
forall n. Int -> HashQualified n -> HashQualified n
HQ.take Int
len (HashQualified Name -> HashQualified Name)
-> (Referent -> HashQualified Name)
-> Referent
-> HashQualified Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Referent -> HashQualified Name
forall n. n -> Referent -> HashQualified n
HQ.fromNamedReferent Name
name

-- | Pretty-print a reference as the given number of characters of its hash.
prettyReference :: Int -> Reference -> Pretty SyntaxText
prettyReference :: Int -> Reference -> Pretty SyntaxText
prettyReference Int
len =
  HashQualified Name -> Pretty SyntaxText
prettyHashQualified (HashQualified Name -> Pretty SyntaxText)
-> (Reference -> HashQualified Name)
-> Reference
-> Pretty SyntaxText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> HashQualified Name -> HashQualified Name
forall n. Int -> HashQualified n -> HashQualified n
HQ.take Int
len (HashQualified Name -> HashQualified Name)
-> (Reference -> HashQualified Name)
-> Reference
-> HashQualified Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> HashQualified Name
HQ.fromReference

-- | Pretty-print a referent as the given number of characters of its hash.
prettyReferent :: Int -> Referent -> Pretty SyntaxText
prettyReferent :: Int -> Referent -> Pretty SyntaxText
prettyReferent Int
len =
  HashQualified Name -> Pretty SyntaxText
prettyHashQualified (HashQualified Name -> Pretty SyntaxText)
-> (Referent -> HashQualified Name)
-> Referent
-> Pretty SyntaxText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> HashQualified Name -> HashQualified Name
forall n. Int -> HashQualified n -> HashQualified n
HQ.take Int
len (HashQualified Name -> HashQualified Name)
-> (Referent -> HashQualified Name)
-> Referent
-> HashQualified Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Referent -> HashQualified Name
HQ.fromReferent

prettyLabeledDependency :: Int -> LabeledDependency -> Pretty SyntaxText
prettyLabeledDependency :: Int -> LabeledDependency -> Pretty SyntaxText
prettyLabeledDependency Int
len = (Reference -> Pretty SyntaxText)
-> (Referent -> Pretty SyntaxText)
-> LabeledDependency
-> Pretty SyntaxText
forall a.
(Reference -> a) -> (Referent -> a) -> LabeledDependency -> a
LD.fold (Int -> Reference -> Pretty SyntaxText
prettyReference Int
len) (Int -> Referent -> Pretty SyntaxText
prettyReferent Int
len)

prettyShortHash :: (IsString s) => ShortHash -> Pretty s
prettyShortHash :: forall s. IsString s => ShortHash -> Pretty s
prettyShortHash = String -> Pretty s
forall a. IsString a => String -> a
fromString (String -> Pretty s)
-> (ShortHash -> String) -> ShortHash -> Pretty s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
Text.unpack (Text -> String) -> (ShortHash -> Text) -> ShortHash -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShortHash -> Text
SH.toText

styleHashQualified ::
  (IsString s) => (Pretty s -> Pretty s) -> HQ.HashQualified Name -> Pretty s
styleHashQualified :: forall s.
IsString s =>
(Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
styleHashQualified Pretty s -> Pretty s
style HashQualified Name
hq = (Pretty s -> Pretty s)
-> (Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
forall s.
IsString s =>
(Pretty s -> Pretty s)
-> (Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
styleHashQualified' Pretty s -> Pretty s
style Pretty s -> Pretty s
forall a. a -> a
id HashQualified Name
hq

styleHashQualified' ::
  (IsString s) =>
  (Pretty s -> Pretty s) ->
  (Pretty s -> Pretty s) ->
  HQ.HashQualified Name ->
  Pretty s
styleHashQualified' :: forall s.
IsString s =>
(Pretty s -> Pretty s)
-> (Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
styleHashQualified' Pretty s -> Pretty s
nameStyle Pretty s -> Pretty s
hashStyle = \case
  HQ.NameOnly Name
n -> Pretty s -> Pretty s
nameStyle (Name -> Pretty s
forall s. IsString s => Name -> Pretty s
prettyName Name
n)
  HQ.HashOnly ShortHash
h -> Pretty s -> Pretty s
hashStyle (ShortHash -> Pretty s
forall s. IsString s => ShortHash -> Pretty s
prettyShortHash ShortHash
h)
  HQ.HashQualified Name
n ShortHash
h ->
    Pretty s -> Pretty s
forall s. Pretty s -> Pretty s
PP.group (Pretty s -> Pretty s) -> Pretty s -> Pretty s
forall a b. (a -> b) -> a -> b
$ Pretty s -> Pretty s
nameStyle (Name -> Pretty s
forall s. IsString s => Name -> Pretty s
prettyName Name
n) Pretty s -> Pretty s -> Pretty s
forall a. Semigroup a => a -> a -> a
<> Pretty s -> Pretty s
hashStyle (ShortHash -> Pretty s
forall s. IsString s => ShortHash -> Pretty s
prettyShortHash ShortHash
h)

styleHashQualified'' ::
  (Pretty SyntaxText -> Pretty SyntaxText) ->
  HQ.HashQualified Name ->
  Pretty SyntaxText
styleHashQualified'' :: (Pretty SyntaxText -> Pretty SyntaxText)
-> HashQualified Name -> Pretty SyntaxText
styleHashQualified'' Pretty SyntaxText -> Pretty SyntaxText
nameStyle HashQualified Name
hq =
  (Pretty SyntaxText -> Pretty SyntaxText)
-> (Pretty SyntaxText -> Pretty SyntaxText)
-> HashQualified Name
-> Pretty SyntaxText
forall s.
IsString s =>
(Pretty s -> Pretty s)
-> (Pretty s -> Pretty s) -> HashQualified Name -> Pretty s
styleHashQualified' Pretty SyntaxText -> Pretty SyntaxText
nameStyle (Element Reference -> Pretty SyntaxText -> Pretty SyntaxText
forall r.
Element r -> Pretty (SyntaxText' r) -> Pretty (SyntaxText' r)
fmt (Element Reference -> Pretty SyntaxText -> Pretty SyntaxText)
-> Element Reference -> Pretty SyntaxText -> Pretty SyntaxText
forall a b. (a -> b) -> a -> b
$ HashQualified Name -> Element Reference
forall r. HashQualified Name -> Element r
S.HashQualifier HashQualified Name
hq) HashQualified Name
hq

fmt :: S.Element r -> Pretty (S.SyntaxText' r) -> Pretty (S.SyntaxText' r)
fmt :: forall r.
Element r -> Pretty (SyntaxText' r) -> Pretty (SyntaxText' r)
fmt = Element r -> Pretty (SyntaxText' r) -> Pretty (SyntaxText' r)
forall r.
Element r -> Pretty (SyntaxText' r) -> Pretty (SyntaxText' r)
PP.withSyntax