-- Copyright (c) 2016-present, Facebook, Inc.
-- All rights reserved.
--
-- This source code is licensed under the BSD-style license found in the
-- LICENSE file in the root directory of this source tree.


{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoRebindableSyntax #-}

module Duckling.Numeral.Rules
  ( rules
  ) where

import Prelude

import Duckling.Dimensions.Types
import Duckling.Numeral.Helpers
import Duckling.Regex.Types
import Duckling.Types

ruleIntegerNumeric :: Rule
ruleIntegerNumeric :: Rule
ruleIntegerNumeric = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"integer (numeric)"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d{1,18})"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (match:_)):[Token]
_) ->
        Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Maybe Int -> Maybe Integer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> Maybe Int
parseInt Text
match Maybe Integer -> (Integer -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Integer -> Maybe Token
integer
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

ruleFractions :: Rule
ruleFractions :: Rule
ruleFractions = Rule :: Text -> Pattern -> Production -> Rule
Rule
  { name :: Text
name = Text
"fractional number"
  , pattern :: Pattern
pattern =
    [ String -> PatternItem
regex String
"(\\d+)/(\\d+)"
    ]
  , prod :: Production
prod = \[Token]
tokens -> case [Token]
tokens of
      (Token Dimension a
RegexMatch (GroupMatch (numerator:denominator:_)):[Token]
_) -> do
        Token
n <- Bool -> Text -> Maybe Token
parseDecimal Bool
False Text
numerator
        Token
d <- Bool -> Text -> Maybe Token
parseDecimal Bool
False Text
denominator
        Token -> Token -> Maybe Token
divide Token
n Token
d Maybe Token -> (Token -> Maybe Token) -> Maybe Token
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Token -> Maybe Token
notOkForAnyTime
      [Token]
_ -> Maybe Token
forall a. Maybe a
Nothing
  }

rules :: [Rule]
rules :: [Rule]
rules =
  [ Rule
ruleIntegerNumeric
  , Rule
ruleFractions
  ]