ogma-core-1.14.0: src/Data/Diagram/Parser.hs
-- Copyright 2024 United States Government as represented by the Administrator
-- of the National Aeronautics and Space Administration. All Rights Reserved.
--
-- Disclaimers
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may
-- not use this file except in compliance with the License. You may obtain a
-- copy of the License at
--
-- https://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-- License for the specific language governing permissions and limitations
-- under the License.
--
-- | Parsing of diagrams.
module Data.Diagram.Parser
( DiagramFormat(..)
, readDiagram
)
where
-- External imports
import Control.Monad.Except (ExceptT (..))
import qualified Data.ByteString.Lazy as B
-- External imports: auxiliary
import Data.ByteString.Extra as B (safeReadFile)
-- Internal imports: auxiliary
import Command.Errors (ErrorCode, ErrorTriplet (..))
import Data.Diagram (Diagram)
import Data.Diagram.Parser.Dot (parseDiagramDot)
import Data.Diagram.Parser.Mermaid (parseDiagramMermaid)
import Data.Either.Extra (mapLeft)
import Data.ExprPair (ExprPair)
import Data.Location (Location (..))
-- | Diagram formats supported.
data DiagramFormat = Mermaid
| Dot
deriving (Eq, Show)
-- | Read a diagram from a file.
readDiagram :: FilePath -- ^ File containing diagram
-> DiagramFormat -- ^ Format of the input file
-> ExprPair -- ^ Subparser for conditions
-- or edge expressions
-> ExceptT ErrorTriplet IO Diagram
readDiagram fp format exprP = ExceptT $ do
contentEither <- B.safeReadFile fp
let diagramE = do
-- The following functions use Either to return errors. The use of
-- (>>=) to chain functions makes the program stop at the earliest
-- error.
diagFileContent <- contentEither
-- Abtract representation of a state machine diagram.
parseDiagram format diagFileContent exprP
pure $ mapLeft
(\msg -> ErrorTriplet ecCannotReadDiagram msg (LocationFile fp))
diagramE
--- | Generic function to parse a diagram.
parseDiagram :: DiagramFormat -- ^ Format of the input file
-> B.ByteString -- ^ Contents of the diagram
-> ExprPair -- ^ Subparser for conditions or edge
-- expressions
-> Either String Diagram
parseDiagram Dot = parseDiagramDot
parseDiagram Mermaid = parseDiagramMermaid
-- ** Error codes
-- | Error: the diagram cannot be read due to an error opening the file or
-- parsing the file.
ecCannotReadDiagram :: ErrorCode
ecCannotReadDiagram = 1