{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE TemplateHaskell #-}
module Emanote.Model.Link.Rel where
import Commonmark.Extensions.WikiLink qualified as WL
import Data.Aeson (ToJSON)
import Data.IxSet.Typed (Indexable (..), IxSet, ixFun, ixList)
import Data.IxSet.Typed qualified as Ix
import Data.List.NonEmpty qualified as NEL
import Data.Map.Strict qualified as Map
import Data.Text qualified as T
import Emanote.Model.Note (Note, noteDoc, noteRoute)
import Emanote.Route (LMLRoute, ModelRoute)
import Emanote.Route qualified as R
import Emanote.Route.SiteRoute.Type qualified as SR
import Optics.Operators as Lens ((^.))
import Optics.TH (makeLenses)
import Relude
import System.FilePath (normalise, (</>))
import Text.Pandoc.Definition qualified as B
import Text.Pandoc.LinkContext qualified as LC
data Rel = Rel
{
Rel -> LMLRoute
_relFrom :: LMLRoute
,
Rel -> UnresolvedRelTarget
_relTo :: UnresolvedRelTarget
, Rel -> [Block]
_relCtx :: [B.Block]
}
deriving stock (Rel -> Rel -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rel -> Rel -> Bool
$c/= :: Rel -> Rel -> Bool
== :: Rel -> Rel -> Bool
$c== :: Rel -> Rel -> Bool
Eq, Eq Rel
Rel -> Rel -> Bool
Rel -> Rel -> Ordering
Rel -> Rel -> Rel
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
min :: Rel -> Rel -> Rel
$cmin :: Rel -> Rel -> Rel
max :: Rel -> Rel -> Rel
$cmax :: Rel -> Rel -> Rel
>= :: Rel -> Rel -> Bool
$c>= :: Rel -> Rel -> Bool
> :: Rel -> Rel -> Bool
$c> :: Rel -> Rel -> Bool
<= :: Rel -> Rel -> Bool
$c<= :: Rel -> Rel -> Bool
< :: Rel -> Rel -> Bool
$c< :: Rel -> Rel -> Bool
compare :: Rel -> Rel -> Ordering
$ccompare :: Rel -> Rel -> Ordering
Ord, Int -> Rel -> ShowS
[Rel] -> ShowS
Rel -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Rel] -> ShowS
$cshowList :: [Rel] -> ShowS
show :: Rel -> FilePath
$cshow :: Rel -> FilePath
showsPrec :: Int -> Rel -> ShowS
$cshowsPrec :: Int -> Rel -> ShowS
Show)
data UnresolvedRelTarget
= URTWikiLink (WL.WikiLinkType, WL.WikiLink)
| URTResource ModelRoute
| URTVirtual SR.VirtualRoute
deriving stock (UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c/= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
== :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c== :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
Eq, Int -> UnresolvedRelTarget -> ShowS
[UnresolvedRelTarget] -> ShowS
UnresolvedRelTarget -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [UnresolvedRelTarget] -> ShowS
$cshowList :: [UnresolvedRelTarget] -> ShowS
show :: UnresolvedRelTarget -> FilePath
$cshow :: UnresolvedRelTarget -> FilePath
showsPrec :: Int -> UnresolvedRelTarget -> ShowS
$cshowsPrec :: Int -> UnresolvedRelTarget -> ShowS
Show, Eq UnresolvedRelTarget
UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
UnresolvedRelTarget -> UnresolvedRelTarget -> Ordering
UnresolvedRelTarget -> UnresolvedRelTarget -> UnresolvedRelTarget
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
min :: UnresolvedRelTarget -> UnresolvedRelTarget -> UnresolvedRelTarget
$cmin :: UnresolvedRelTarget -> UnresolvedRelTarget -> UnresolvedRelTarget
max :: UnresolvedRelTarget -> UnresolvedRelTarget -> UnresolvedRelTarget
$cmax :: UnresolvedRelTarget -> UnresolvedRelTarget -> UnresolvedRelTarget
>= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c>= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
> :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c> :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
<= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c<= :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
< :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
$c< :: UnresolvedRelTarget -> UnresolvedRelTarget -> Bool
compare :: UnresolvedRelTarget -> UnresolvedRelTarget -> Ordering
$ccompare :: UnresolvedRelTarget -> UnresolvedRelTarget -> Ordering
Ord, forall x. Rep UnresolvedRelTarget x -> UnresolvedRelTarget
forall x. UnresolvedRelTarget -> Rep UnresolvedRelTarget x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep UnresolvedRelTarget x -> UnresolvedRelTarget
$cfrom :: forall x. UnresolvedRelTarget -> Rep UnresolvedRelTarget x
Generic)
deriving anyclass ([UnresolvedRelTarget] -> Encoding
[UnresolvedRelTarget] -> Value
UnresolvedRelTarget -> Encoding
UnresolvedRelTarget -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [UnresolvedRelTarget] -> Encoding
$ctoEncodingList :: [UnresolvedRelTarget] -> Encoding
toJSONList :: [UnresolvedRelTarget] -> Value
$ctoJSONList :: [UnresolvedRelTarget] -> Value
toEncoding :: UnresolvedRelTarget -> Encoding
$ctoEncoding :: UnresolvedRelTarget -> Encoding
toJSON :: UnresolvedRelTarget -> Value
$ctoJSON :: UnresolvedRelTarget -> Value
ToJSON)
type RelIxs = '[LMLRoute, UnresolvedRelTarget]
type IxRel = IxSet RelIxs Rel
instance Indexable RelIxs Rel where
indices :: IxList RelIxs Rel
indices =
forall (ixs :: [Type]) a r. MkIxList ixs ixs a r => r
ixList
(forall ix a. Ord ix => (a -> [ix]) -> Ix ix a
ixFun forall a b. (a -> b) -> a -> b
$ forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rel -> LMLRoute
_relFrom)
(forall ix a. Ord ix => (a -> [ix]) -> Ix ix a
ixFun forall a b. (a -> b) -> a -> b
$ forall x. One x => OneItem x -> x
one forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rel -> UnresolvedRelTarget
_relTo)
makeLenses ''Rel
noteRels :: Note -> IxRel
noteRels :: Note -> IxRel
noteRels Note
note =
Map Text (NonEmpty ([(Text, Text)], [Block])) -> IxRel
extractLinks forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pandoc -> Map Text (NonEmpty ([(Text, Text)], [Block]))
LC.queryLinksWithContext forall a b. (a -> b) -> a -> b
$ Note
note forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' Note Pandoc
noteDoc
where
extractLinks :: Map Text (NonEmpty ([(Text, Text)], [B.Block])) -> IxRel
extractLinks :: Map Text (NonEmpty ([(Text, Text)], [Block])) -> IxRel
extractLinks Map Text (NonEmpty ([(Text, Text)], [Block]))
m =
forall (ixs :: [Type]) a. Indexable ixs a => [a] -> IxSet ixs a
Ix.fromList forall a b. (a -> b) -> a -> b
$
forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (t :: Type -> Type) a b.
Foldable t =>
(a -> [b]) -> t a -> [b]
concatMap (forall k a. Map k a -> [(k, a)]
Map.toList Map Text (NonEmpty ([(Text, Text)], [Block]))
m) forall a b. (a -> b) -> a -> b
$ \(Text
url, NonEmpty ([(Text, Text)], [Block])
instances) -> do
forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList NonEmpty ([(Text, Text)], [Block])
instances) forall a b. (a -> b) -> a -> b
$ \([(Text, Text)]
attrs, [Block]
ctx) -> do
let parentR :: Maybe (R @() 'Folder)
parentR = forall r.
(forall (lmlType :: LML).
HasExt @SourceExt ('LMLType lmlType) =>
R @SourceExt ('LMLType lmlType) -> r)
-> LMLRoute -> r
R.withLmlRoute forall {a} (ext :: FileType a). R @a ext -> Maybe (R @() 'Folder)
R.routeParent forall a b. (a -> b) -> a -> b
$ Note
note forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' Note LMLRoute
noteRoute
(UnresolvedRelTarget
target, Maybe Anchor
_manchor) <- Maybe (R @() 'Folder)
-> [(Text, Text)]
-> Text
-> Maybe (UnresolvedRelTarget, Maybe Anchor)
parseUnresolvedRelTarget Maybe (R @() 'Folder)
parentR [(Text, Text)]
attrs Text
url
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ LMLRoute -> UnresolvedRelTarget -> [Block] -> Rel
Rel (Note
note forall k s (is :: [Type]) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Lens' Note LMLRoute
noteRoute) UnresolvedRelTarget
target [Block]
ctx
unresolvedRelsTo :: ModelRoute -> [UnresolvedRelTarget]
unresolvedRelsTo :: ModelRoute -> [UnresolvedRelTarget]
unresolvedRelsTo ModelRoute
r =
let allowedWikiLinks :: R @a ext -> NonEmpty (WikiLinkType, WikiLink)
allowedWikiLinks = HasCallStack => NonEmpty Slug -> NonEmpty (WikiLinkType, WikiLink)
WL.allowedWikiLinks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a (ext :: FileType a). R @a ext -> NonEmpty Slug
R.unRoute
wls :: NonEmpty (WikiLinkType, WikiLink)
wls = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall r.
(forall (lmlType :: LML).
HasExt @SourceExt ('LMLType lmlType) =>
R @SourceExt ('LMLType lmlType) -> r)
-> LMLRoute -> r
R.withLmlRoute forall {a} {ext :: FileType a}.
R @a ext -> NonEmpty (WikiLinkType, WikiLink)
allowedWikiLinks) forall {a} {ext :: FileType a}.
R @a ext -> NonEmpty (WikiLinkType, WikiLink)
allowedWikiLinks forall a b. (a -> b) -> a -> b
$ ModelRoute -> Either LMLRoute StaticFileRoute
R.modelRouteCase ModelRoute
r
in ((WikiLinkType, WikiLink) -> UnresolvedRelTarget
URTWikiLink forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList NonEmpty (WikiLinkType, WikiLink)
wls)
forall a. Semigroup a => a -> a -> a
<> [ModelRoute -> UnresolvedRelTarget
URTResource ModelRoute
r]
parseUnresolvedRelTarget :: Maybe (R.R 'R.Folder) -> [(Text, Text)] -> Text -> Maybe (UnresolvedRelTarget, Maybe WL.Anchor)
parseUnresolvedRelTarget :: Maybe (R @() 'Folder)
-> [(Text, Text)]
-> Text
-> Maybe (UnresolvedRelTarget, Maybe Anchor)
parseUnresolvedRelTarget Maybe (R @() 'Folder)
baseDir [(Text, Text)]
attrs Text
url = do
(Either (WikiLinkType, WikiLink) FilePath
wlRes, Maybe Anchor
manchor) <- [(Text, Text)]
-> Text
-> Maybe (Either (WikiLinkType, WikiLink) FilePath, Maybe Anchor)
WL.delineateLink [(Text, Text)]
attrs Text
url
UnresolvedRelTarget
res <- case Either (WikiLinkType, WikiLink) FilePath
wlRes of
Left (WikiLinkType, WikiLink)
wl ->
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ (WikiLinkType, WikiLink) -> UnresolvedRelTarget
URTWikiLink (WikiLinkType, WikiLink)
wl
Right FilePath
fp ->
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap VirtualRoute -> UnresolvedRelTarget
URTVirtual (FilePath -> Maybe VirtualRoute
SR.decodeVirtualRoute FilePath
fp)
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap
ModelRoute -> UnresolvedRelTarget
URTResource
( FilePath
fp
forall a b. a -> (a -> b) -> b
& Maybe FilePath -> ShowS
relocateRelUrlUnder (forall a (ft :: FileType a). HasExt @a ft => R @a ft -> FilePath
R.encodeRoute forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (R @() 'Folder)
baseDir)
forall a b. a -> (a -> b) -> b
& FilePath -> Maybe ModelRoute
R.mkModelRouteFromFilePath
)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (UnresolvedRelTarget
res, Maybe Anchor
manchor)
relocateRelUrlUnder :: Maybe FilePath -> FilePath -> FilePath
relocateRelUrlUnder :: Maybe FilePath -> ShowS
relocateRelUrlUnder Maybe FilePath
mbase FilePath
fp =
ShowS
normalizeIgnoringSymlinks forall a b. (a -> b) -> a -> b
$
case Maybe FilePath
mbase of
Maybe FilePath
Nothing -> FilePath
fp
Just FilePath
x -> FilePath
x FilePath -> ShowS
</> FilePath
fp
normalizeIgnoringSymlinks :: FilePath -> FilePath
normalizeIgnoringSymlinks :: ShowS
normalizeIgnoringSymlinks = ShowS
dropDotDot forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
normalise
dropDotDot :: FilePath -> FilePath
dropDotDot :: ShowS
dropDotDot =
let go :: Int -> NonEmpty Text -> [Text]
go :: Int -> NonEmpty Text -> [Text]
go Int
n = \case
(Text
".." :| [Text]
xs) -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Int -> NonEmpty Text -> [Text]
go forall a b. (a -> b) -> a -> b
$ Int
n forall a. Num a => a -> a -> a
+ Int
1) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Text]
xs
(Text
x :| [Text]
xs) | Int
n forall a. Eq a => a -> a -> Bool
== Int
0 -> Text
x forall a. a -> [a] -> [a]
: forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Int -> NonEmpty Text -> [Text]
go Int
0) (forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Text]
xs)
NonEmpty Text
x -> forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Int -> NonEmpty Text -> [Text]
go Int
0) forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe (NonEmpty a)
nonEmpty forall a b. (a -> b) -> a -> b
$ forall a. Int -> NonEmpty a -> [a]
NEL.drop Int
n NonEmpty Text
x
in forall a. ToString a => a -> FilePath
toString forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> Text
T.intercalate Text
"/" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (forall a. [a] -> [a]
reverse forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> NonEmpty Text -> [Text]
go Int
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> NonEmpty a
NEL.reverse) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> Maybe (NonEmpty a)
nonEmpty forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> [Text]
T.splitOn Text
"/" forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToText a => a -> Text
toText
data ResolvedRelTarget a
= RRTMissing
| RRTAmbiguous (NonEmpty a)
| RRTFound a
deriving stock (ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
forall a.
Eq a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c/= :: forall a.
Eq a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
== :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c== :: forall a.
Eq a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
Eq, Int -> ResolvedRelTarget a -> ShowS
forall a. Show a => Int -> ResolvedRelTarget a -> ShowS
forall a. Show a => [ResolvedRelTarget a] -> ShowS
forall a. Show a => ResolvedRelTarget a -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [ResolvedRelTarget a] -> ShowS
$cshowList :: forall a. Show a => [ResolvedRelTarget a] -> ShowS
show :: ResolvedRelTarget a -> FilePath
$cshow :: forall a. Show a => ResolvedRelTarget a -> FilePath
showsPrec :: Int -> ResolvedRelTarget a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> ResolvedRelTarget a -> ShowS
Show, ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
ResolvedRelTarget a -> ResolvedRelTarget a -> Ordering
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
forall {a}. Ord a => Eq (ResolvedRelTarget a)
forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Ordering
forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> ResolvedRelTarget a
min :: ResolvedRelTarget a -> ResolvedRelTarget a -> ResolvedRelTarget a
$cmin :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> ResolvedRelTarget a
max :: ResolvedRelTarget a -> ResolvedRelTarget a -> ResolvedRelTarget a
$cmax :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> ResolvedRelTarget a
>= :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c>= :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
> :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c> :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
<= :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c<= :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
< :: ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
$c< :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Bool
compare :: ResolvedRelTarget a -> ResolvedRelTarget a -> Ordering
$ccompare :: forall a.
Ord a =>
ResolvedRelTarget a -> ResolvedRelTarget a -> Ordering
Ord, forall a b. a -> ResolvedRelTarget b -> ResolvedRelTarget a
forall a b. (a -> b) -> ResolvedRelTarget a -> ResolvedRelTarget b
forall (f :: Type -> Type).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> ResolvedRelTarget b -> ResolvedRelTarget a
$c<$ :: forall a b. a -> ResolvedRelTarget b -> ResolvedRelTarget a
fmap :: forall a b. (a -> b) -> ResolvedRelTarget a -> ResolvedRelTarget b
$cfmap :: forall a b. (a -> b) -> ResolvedRelTarget a -> ResolvedRelTarget b
Functor, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (ResolvedRelTarget a) x -> ResolvedRelTarget a
forall a x. ResolvedRelTarget a -> Rep (ResolvedRelTarget a) x
$cto :: forall a x. Rep (ResolvedRelTarget a) x -> ResolvedRelTarget a
$cfrom :: forall a x. ResolvedRelTarget a -> Rep (ResolvedRelTarget a) x
Generic)
deriving anyclass (forall a. ToJSON a => [ResolvedRelTarget a] -> Encoding
forall a. ToJSON a => [ResolvedRelTarget a] -> Value
forall a. ToJSON a => ResolvedRelTarget a -> Encoding
forall a. ToJSON a => ResolvedRelTarget a -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
toEncodingList :: [ResolvedRelTarget a] -> Encoding
$ctoEncodingList :: forall a. ToJSON a => [ResolvedRelTarget a] -> Encoding
toJSONList :: [ResolvedRelTarget a] -> Value
$ctoJSONList :: forall a. ToJSON a => [ResolvedRelTarget a] -> Value
toEncoding :: ResolvedRelTarget a -> Encoding
$ctoEncoding :: forall a. ToJSON a => ResolvedRelTarget a -> Encoding
toJSON :: ResolvedRelTarget a -> Value
$ctoJSON :: forall a. ToJSON a => ResolvedRelTarget a -> Value
ToJSON)
resolvedRelTargetFromCandidates :: [a] -> ResolvedRelTarget a
resolvedRelTargetFromCandidates :: forall a. [a] -> ResolvedRelTarget a
resolvedRelTargetFromCandidates [a]
xs =
case forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [a]
xs of
Maybe (NonEmpty a)
Nothing ->
forall a. ResolvedRelTarget a
RRTMissing
Just (a
x :| []) ->
forall a. a -> ResolvedRelTarget a
RRTFound a
x
Just NonEmpty a
xs' ->
forall a. NonEmpty a -> ResolvedRelTarget a
RRTAmbiguous NonEmpty a
xs'