module Unison.Name.Forward where

import Data.List qualified as List
import Data.List.NonEmpty (NonEmpty ((:|)), nonEmpty)
import Unison.Name qualified as Name
import Unison.Name.Internal (Name)
import Unison.NameSegment (NameSegment)

newtype ForwardName = ForwardName {ForwardName -> NonEmpty NameSegment
toList :: NonEmpty NameSegment} deriving (ForwardName -> ForwardName -> Bool
(ForwardName -> ForwardName -> Bool)
-> (ForwardName -> ForwardName -> Bool) -> Eq ForwardName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ForwardName -> ForwardName -> Bool
== :: ForwardName -> ForwardName -> Bool
$c/= :: ForwardName -> ForwardName -> Bool
/= :: ForwardName -> ForwardName -> Bool
Eq, Eq ForwardName
Eq ForwardName =>
(ForwardName -> ForwardName -> Ordering)
-> (ForwardName -> ForwardName -> Bool)
-> (ForwardName -> ForwardName -> Bool)
-> (ForwardName -> ForwardName -> Bool)
-> (ForwardName -> ForwardName -> Bool)
-> (ForwardName -> ForwardName -> ForwardName)
-> (ForwardName -> ForwardName -> ForwardName)
-> Ord ForwardName
ForwardName -> ForwardName -> Bool
ForwardName -> ForwardName -> Ordering
ForwardName -> ForwardName -> ForwardName
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 :: ForwardName -> ForwardName -> Ordering
compare :: ForwardName -> ForwardName -> Ordering
$c< :: ForwardName -> ForwardName -> Bool
< :: ForwardName -> ForwardName -> Bool
$c<= :: ForwardName -> ForwardName -> Bool
<= :: ForwardName -> ForwardName -> Bool
$c> :: ForwardName -> ForwardName -> Bool
> :: ForwardName -> ForwardName -> Bool
$c>= :: ForwardName -> ForwardName -> Bool
>= :: ForwardName -> ForwardName -> Bool
$cmax :: ForwardName -> ForwardName -> ForwardName
max :: ForwardName -> ForwardName -> ForwardName
$cmin :: ForwardName -> ForwardName -> ForwardName
min :: ForwardName -> ForwardName -> ForwardName
Ord, Int -> ForwardName -> ShowS
[ForwardName] -> ShowS
ForwardName -> String
(Int -> ForwardName -> ShowS)
-> (ForwardName -> String)
-> ([ForwardName] -> ShowS)
-> Show ForwardName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ForwardName -> ShowS
showsPrec :: Int -> ForwardName -> ShowS
$cshow :: ForwardName -> String
show :: ForwardName -> String
$cshowList :: [ForwardName] -> ShowS
showList :: [ForwardName] -> ShowS
Show)

-- | O(d)
fromName :: Name -> ForwardName
fromName :: Name -> ForwardName
fromName Name
n = NonEmpty NameSegment -> ForwardName
ForwardName (NonEmpty NameSegment -> ForwardName)
-> NonEmpty NameSegment -> ForwardName
forall a b. (a -> b) -> a -> b
$ Name -> NonEmpty NameSegment
Name.segments Name
n

stripNamePrefix :: ForwardName -> ForwardName -> Maybe ForwardName
stripNamePrefix :: ForwardName -> ForwardName -> Maybe ForwardName
stripNamePrefix (ForwardName (NameSegment
p :| [NameSegment]
ps)) (ForwardName (NameSegment
n :| [NameSegment]
ns)) =
  if NameSegment
p NameSegment -> NameSegment -> Bool
forall a. Eq a => a -> a -> Bool
/= NameSegment
n
    then Maybe ForwardName
forall a. Maybe a
Nothing
    else NonEmpty NameSegment -> ForwardName
ForwardName (NonEmpty NameSegment -> ForwardName)
-> Maybe (NonEmpty NameSegment) -> Maybe ForwardName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty NameSegment)
-> ([NameSegment] -> Maybe (NonEmpty NameSegment))
-> Maybe [NameSegment]
-> Maybe (NonEmpty NameSegment)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Maybe (NonEmpty NameSegment)
forall a. Maybe a
Nothing [NameSegment] -> Maybe (NonEmpty NameSegment)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty ([NameSegment] -> [NameSegment] -> Maybe [NameSegment]
forall a. Eq a => [a] -> [a] -> Maybe [a]
List.stripPrefix [NameSegment]
ps [NameSegment]
ns)