module Unison.Server.NameSearch.FromNames where

import Unison.HashQualifiedPrime qualified as HQ'
import Unison.Names (Names)
import Unison.NamesWithHistory qualified as Names
import Unison.Reference (Reference)
import Unison.Referent (Referent)
import Unison.Server.NameSearch
import Unison.Server.SearchResult qualified as SR

-- | Make a type search, given a short hash length and names to search in.
makeTypeSearch :: (Applicative m) => Int -> Names -> Search m Reference
makeTypeSearch :: forall (m :: * -> *).
Applicative m =>
Int -> Names -> Search m Reference
makeTypeSearch Int
len Names
names =
  Search
    { $sel:lookupNames:Search :: Reference -> m (Set (HashQualified Name))
lookupNames = \Reference
ref -> Set (HashQualified Name) -> m (Set (HashQualified Name))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set (HashQualified Name) -> m (Set (HashQualified Name)))
-> Set (HashQualified Name) -> m (Set (HashQualified Name))
forall a b. (a -> b) -> a -> b
$ Int -> Reference -> Names -> Set (HashQualified Name)
Names.typeName Int
len Reference
ref Names
names,
      $sel:lookupRelativeHQRefs':Search :: SearchType -> HashQualified Name -> m (Set Reference)
lookupRelativeHQRefs' = \SearchType
searchType HashQualified Name
n -> Set Reference -> m (Set Reference)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set Reference -> m (Set Reference))
-> Set Reference -> m (Set Reference)
forall a b. (a -> b) -> a -> b
$ SearchType -> HashQualified Name -> Names -> Set Reference
Names.lookupRelativeHQType' SearchType
searchType HashQualified Name
n Names
names,
      $sel:matchesNamedRef:Search :: Name -> Reference -> HashQualified Name -> Bool
matchesNamedRef = Name -> Reference -> HashQualified Name -> Bool
forall n. Eq n => n -> Reference -> HashQualified n -> Bool
HQ'.matchesNamedReference,
      $sel:makeResult:Search :: HashQualified Name
-> Reference -> Set (HashQualified Name) -> m SearchResult
makeResult = \HashQualified Name
hqname Reference
r Set (HashQualified Name)
names -> SearchResult -> m SearchResult
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SearchResult -> m SearchResult) -> SearchResult -> m SearchResult
forall a b. (a -> b) -> a -> b
$ HashQualified Name
-> Reference -> Set (HashQualified Name) -> SearchResult
SR.typeResult HashQualified Name
hqname Reference
r Set (HashQualified Name)
names
    }

-- | Make a term search, given a short hash length and names to search in.
makeTermSearch :: (Applicative m) => Int -> Names -> Search m Referent
makeTermSearch :: forall (m :: * -> *).
Applicative m =>
Int -> Names -> Search m Referent
makeTermSearch Int
len Names
names =
  Search
    { $sel:lookupNames:Search :: Referent -> m (Set (HashQualified Name))
lookupNames = \Referent
ref -> Set (HashQualified Name) -> m (Set (HashQualified Name))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set (HashQualified Name) -> m (Set (HashQualified Name)))
-> Set (HashQualified Name) -> m (Set (HashQualified Name))
forall a b. (a -> b) -> a -> b
$ Int -> Referent -> Names -> Set (HashQualified Name)
Names.termName Int
len Referent
ref Names
names,
      $sel:lookupRelativeHQRefs':Search :: SearchType -> HashQualified Name -> m (Set Referent)
lookupRelativeHQRefs' = \SearchType
searchType HashQualified Name
n -> Set Referent -> m (Set Referent)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Set Referent -> m (Set Referent))
-> Set Referent -> m (Set Referent)
forall a b. (a -> b) -> a -> b
$ SearchType -> HashQualified Name -> Names -> Set Referent
Names.lookupRelativeHQTerm' SearchType
searchType HashQualified Name
n Names
names,
      $sel:matchesNamedRef:Search :: Name -> Referent -> HashQualified Name -> Bool
matchesNamedRef = Name -> Referent -> HashQualified Name -> Bool
forall n. Eq n => n -> Referent -> HashQualified n -> Bool
HQ'.matchesNamedReferent,
      $sel:makeResult:Search :: HashQualified Name
-> Referent -> Set (HashQualified Name) -> m SearchResult
makeResult = \HashQualified Name
hqname Referent
r Set (HashQualified Name)
names -> SearchResult -> m SearchResult
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SearchResult -> m SearchResult) -> SearchResult -> m SearchResult
forall a b. (a -> b) -> a -> b
$ HashQualified Name
-> Referent -> Set (HashQualified Name) -> SearchResult
SR.termResult HashQualified Name
hqname Referent
r Set (HashQualified Name)
names
    }

makeNameSearch :: (Applicative m) => Int -> Names -> NameSearch m
makeNameSearch :: forall (m :: * -> *). Applicative m => Int -> Names -> NameSearch m
makeNameSearch Int
hashLength Names
names =
  NameSearch
    { $sel:typeSearch:NameSearch :: Search m Reference
typeSearch = Int -> Names -> Search m Reference
forall (m :: * -> *).
Applicative m =>
Int -> Names -> Search m Reference
makeTypeSearch Int
hashLength Names
names,
      $sel:termSearch:NameSearch :: Search m Referent
termSearch = Int -> Names -> Search m Referent
forall (m :: * -> *).
Applicative m =>
Int -> Names -> Search m Referent
makeTermSearch Int
hashLength Names
names
    }