git.iko.soy/typeable/cabal2nix
on 835beff help sign in
53 lines 1.7 kB history raw
1{-# LANGUAGE DeriveGeneric #-}
3module Language.Nix.Path ( Path, path ) where
5import Internal.Lens
6import Internal.PrettyPrinting ( Pretty (..), char, hcat, punctuate )
7import Language.Nix.Identifier
8import Control.DeepSeq.Generics
9import GHC.Generics ( Generic )
11-- | Paths are non-empty lists of identifiers in Nix.
12--
13-- >>> set path [set ident "yo" undefined] undefined
14-- Path {_segments = [Identifier "yo"]}
15--
16-- Any attempt to construct the empty path throws an 'error':
17--
18-- >>> set path [] undefined
19-- Path {_segments = *** Exception: Nix paths cannot be empty
20--
21-- 'Identifier' is an instance of 'IsString':
22--
23-- >>> :set -XOverloadedStrings
24-- >>> pPrint $ set path ["yo","bar"] undefined
25-- yo.bar
26--
27-- Freaky quoted identifiers are fine except in the first segment:
28--
29-- >>> pPrint $ set path ["yo","b\"ar"] undefined
30-- yo."b\"ar"
31-- >>> pPrint $ set path ["5ident"] undefined
32-- *** Exception: invalid Nix path: [Identifier "5ident"]
33-- >>> pPrint $ set path ["5ident","foo","bar"] undefined
34-- *** Exception: invalid Nix path: [Identifier "5ident",Identifier "foo",Identifier "bar"]
36newtype Path = Path { _segments :: [Identifier] }
37 deriving (Show, Eq, Ord, Generic)
39instance NFData Path where rnf = genericRnf
41instance Default Path where def = Path (error "undefined Nix.Path")
43path :: Lens' Path [Identifier]
44path f (Path ids) = mkPath `fmap` f ids
45 where
46 mkPath :: [Identifier] -> Path
47 mkPath [] = error "Nix paths cannot be empty"
48 mkPath p@(s0:_)
49 | s0^.ident.to needsQuoting = error ("invalid Nix path: " ++ show p)
50 | otherwise = Path p
52instance Pretty Path where
53 pPrint p = hcat $ punctuate (char '.') $ pPrint <$> p^.path