-- Copyright (c) Microsoft. All rights reserved. -- Licensed under the MIT license. See LICENSE file in the project root for full license information. {-# LANGUAGE OverloadedStrings #-} module Language.Bond.Codegen.CustomMapping ( AliasMapping(..) , Fragment(..) , NamespaceMapping(..) , parseAliasMapping , parseNamespaceMapping ) where import Data.Char import Control.Applicative import Prelude import Text.Parsec hiding (many, optional, (<|>)) import Language.Bond.Syntax.Types -- | Specification of a fragment of type alias mappings. data Fragment = Fragment String | -- ^ hardcoded string fragment Placeholder Int -- ^ placeholder for the n-th type argument of the type alias, applicable only to generic aliases -- | Specification of a type alias mapping. data AliasMapping = AliasMapping { aliasName :: QualifiedName -- ^ qualified name of a type alias , aliasTemplate :: [Fragment] -- ^ list of fragments comprising custom mapping for the alias } -- | Specification of namespace mapping. data NamespaceMapping = NamespaceMapping { fromNamespace :: QualifiedName -- ^ schema namespace , toNamespace :: QualifiedName -- ^ namespace in the generated code } type Parser a = Parsec SourceName () a whitespace :: Parser String whitespace = many (char ' ') "whitespace" identifier :: Parser String identifier = many1 (alphaNum <|> char '_') "identifier" qualifiedName :: Parser [String] qualifiedName = sepBy1 identifier (char '.') "qualified name" symbol :: String -> Parser String symbol s = whitespace *> string s <* whitespace equal :: Parser String equal = symbol "=" integer :: Parser Integer integer = decimal <$> many1 digit "decimal number" where decimal = foldl (\x d -> 10 * x + toInteger (digitToInt d)) 0 -- | Parse a type alias mapping specification used in command-line arguments of -- . -- -- ==== __Examples__ -- -- > > parseAliasMapping "Example.OrderedSet=SortedSet<{0}>" -- > Right (AliasMapping {aliasName = ["Example","OrderedSet"], aliasTemplate = [Fragment "SortedSet<",Placeholder 0,Fragment ">"]}) parseAliasMapping :: String -> Either ParseError AliasMapping parseAliasMapping s = parse aliasMapping s s where aliasMapping = AliasMapping <$> qualifiedName <* equal <*> many1 (placeholder <|> fragment) <* eof placeholder = Placeholder <$> fromIntegral <$> between (char '{') (char '}') integer fragment = Fragment <$> many1 (noneOf "{") -- | Parse a namespace mapping specification used in command-line arguments of -- . -- -- ==== __Examples__ -- -- > > parseNamespaceMapping "bond=Microsoft.Bond" -- > Right (NamespaceMapping {fromNamespace = ["bond"], toNamespace = ["Microsoft","Bond"]}) parseNamespaceMapping :: String -> Either ParseError NamespaceMapping parseNamespaceMapping s = parse namespaceMapping s s where namespaceMapping = NamespaceMapping <$> qualifiedName <* equal <*> qualifiedName