summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MdBlocks/CLI.hs6
-rw-r--r--src/MdBlocks/Resolver.hs75
2 files changed, 56 insertions, 25 deletions
diff --git a/src/MdBlocks/CLI.hs b/src/MdBlocks/CLI.hs
index 5c2bc29..3849220 100644
--- a/src/MdBlocks/CLI.hs
+++ b/src/MdBlocks/CLI.hs
@@ -81,10 +81,10 @@ run (Extract rawAddress) =
blocks <- loadBlocks (addressFile address)
case resolveBlock address blocks of
- Nothing ->
- die ("mdblocks: block not found: " ++ rawAddress)
+ Left err ->
+ die ("mdblocks: " ++ formatResolveError address err)
- Just block ->
+ Right block ->
T.putStr (blockContent block)
run (ShowMeta addr) =
diff --git a/src/MdBlocks/Resolver.hs b/src/MdBlocks/Resolver.hs
index 29c1658..1713a16 100644
--- a/src/MdBlocks/Resolver.hs
+++ b/src/MdBlocks/Resolver.hs
@@ -1,37 +1,68 @@
module MdBlocks.Resolver
- ( resolveBlock
+ ( ResolveError(..)
+ , resolveBlock
+ , formatResolveError
)
where
-import Data.Text (Text)
+import Data.List (intercalate)
+import qualified Data.Text as T
import MdBlocks.Address
import MdBlocks.Types
+data ResolveError
+ = BlockNotFound
+ | DuplicateBlockId [Block]
+ deriving (Show, Eq)
+
resolveBlock
:: Address
-> [Block]
- -> Maybe Block
-resolveBlock address =
- findByFileAndId
- (addressFile address)
- (addressId address)
+ -> Either ResolveError Block
+resolveBlock address blocks =
+ case matches of
+ [] ->
+ Left BlockNotFound
-findByFileAndId
- :: FilePath
- -> Text
- -> [Block]
- -> Maybe Block
-findByFileAndId fp ident =
- go
+ [block] ->
+ Right block
+
+ many ->
+ Left (DuplicateBlockId many)
where
- go [] =
- Nothing
+ matches =
+ [ b
+ | b <- blocks
+ , blockFile b == addressFile address
+ , mdId (blockMeta b) == Just (addressId address)
+ ]
+
+formatResolveError
+ :: Address
+ -> ResolveError
+ -> String
+formatResolveError address err =
+ case err of
+ BlockNotFound ->
+ "block not found: "
+ ++ showAddress address
+
+ DuplicateBlockId blocks ->
+ "duplicate block id '"
+ ++ T.unpack (addressId address)
+ ++ "' in "
+ ++ addressFile address
+ ++ "\n found at "
+ ++ formatLines blocks
- go (b:bs)
- | blockFile b == fp
- , mdId (blockMeta b) == Just ident =
- Just b
+formatLines :: [Block] -> String
+formatLines blocks =
+ "lines "
+ ++ intercalate ", " (map (show . blockStart) blocks)
- | otherwise =
- go bs
+showAddress :: Address -> String
+showAddress address =
+ addressFile address
+ ++ "#"
+ ++ T.unpack (addressId address)