-- 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. An additional grant -- of patent rights can be found in the PATENTS file in the same directory. {-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} module Duckling.AmountOfMoney.BG.Rules ( rules ) where import Data.Maybe import Data.String import Prelude import qualified Data.Text as Text import Duckling.AmountOfMoney.Helpers import Duckling.AmountOfMoney.Types (Currency(..), AmountOfMoneyData (..)) import Duckling.Dimensions.Types import Duckling.Numeral.Types (NumeralData (..)) import Duckling.Regex.Types import Duckling.Types import qualified Duckling.AmountOfMoney.Types as TAmountOfMoney import qualified Duckling.Numeral.Types as TNumeral ruleBGN :: Rule ruleBGN = Rule { name = "лв" , pattern = [ regex "ле?ва?" ] , prod = \_ -> Just . Token AmountOfMoney $ currencyOnly BGN } rulePounds :: Rule rulePounds = Rule { name = "£" , pattern = [ regex "паунд(а|и)?" ] , prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Pound } ruleDollar :: Rule ruleDollar = Rule { name = "$" , pattern = [ regex "долар(а|и)?" ] , prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Dollar } ruleCent :: Rule ruleCent = Rule { name = "cent" , pattern = [ regex "ст(отинк(a|и))?|цента?|пени(та)?|пенса?|ц" ] , prod = \_ -> Just . Token AmountOfMoney $ currencyOnly Cent } ruleEUR :: Rule ruleEUR = Rule { name = "€" , pattern = [ regex "евр(о|а)" ] , prod = \_ -> Just . Token AmountOfMoney $ currencyOnly EUR } ruleIntersectAndXCents :: Rule ruleIntersectAndXCents = Rule { name = "intersect (and X cents)" , pattern = [ financeWith TAmountOfMoney.value isJust , regex "и" , financeWith TAmountOfMoney.currency (== Cent) ] , prod = \tokens -> case tokens of (Token AmountOfMoney fd: _: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just c}): _) -> Just . Token AmountOfMoney $ withCents c fd _ -> Nothing } ruleIntersect :: Rule ruleIntersect = Rule { name = "intersect" , pattern = [ financeWith TAmountOfMoney.value isJust , dimension Numeral ] , prod = \tokens -> case tokens of (Token AmountOfMoney fd: Token Numeral (NumeralData {TNumeral.value = c}): _) -> Just . Token AmountOfMoney $ withCents c fd _ -> Nothing } ruleIntersectAndNumeral :: Rule ruleIntersectAndNumeral = Rule { name = "intersect (and number)" , pattern = [ financeWith TAmountOfMoney.value isJust , regex "и" , dimension Numeral ] , prod = \tokens -> case tokens of (Token AmountOfMoney fd: _: Token Numeral (NumeralData {TNumeral.value = c}): _) -> Just . Token AmountOfMoney $ withCents c fd _ -> Nothing } ruleIntersectXCents :: Rule ruleIntersectXCents = Rule { name = "intersect (X cents)" , pattern = [ financeWith TAmountOfMoney.value isJust , financeWith id $ \x -> case TAmountOfMoney.value x of Just v | v > 0 -> TAmountOfMoney.currency x == Cent _ -> False ] , prod = \tokens -> case tokens of (Token AmountOfMoney fd: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just c}): _) -> Just . Token AmountOfMoney $ withCents c fd _ -> Nothing } rulePrecision :: Rule rulePrecision = Rule { name = "about|exactly " , pattern = [ regex "точно|около|приблизително|близо (до)?|почти" , dimension AmountOfMoney ] , prod = \tokens -> case tokens of (_:token:_) -> Just token _ -> Nothing } ruleIntervalBetweenNumeral :: Rule ruleIntervalBetweenNumeral = Rule { name = "between|from to|and " , pattern = [ regex "между|от" , dimension Numeral , regex "до|и" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (_: Token Numeral (NumeralData {TNumeral.value = from}): _: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}): _) -> Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c _ -> Nothing } ruleIntervalBetween :: Rule ruleIntervalBetween = Rule { name = "between|from to|and " , pattern = [ regex "между|от" , financeWith TAmountOfMoney.value isJust , regex "до|и" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (_: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}): _: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}): _) | c1 == c2 -> Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1 _ -> Nothing } ruleIntervalNumeralDash :: Rule ruleIntervalNumeralDash = Rule { name = " - " , pattern = [ dimension Numeral , regex "-" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (Token Numeral (NumeralData {TNumeral.value = from}): _: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}): _) -> Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c _ -> Nothing } ruleIntervalDash :: Rule ruleIntervalDash = Rule { name = " - " , pattern = [ financeWith TAmountOfMoney.value isJust , regex "-" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just from, TAmountOfMoney.currency = c1}): _: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c2}): _) | c1 == c2 -> Just . Token AmountOfMoney . withInterval (from, to) $ currencyOnly c1 _ -> Nothing } ruleIntervalMax :: Rule ruleIntervalMax = Rule { name = "under/less/lower/no more than " , pattern = [ regex "под|по-малко от|не повече от" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (_: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}): _) -> Just . Token AmountOfMoney . withMax to $ currencyOnly c _ -> Nothing } ruleIntervalMin :: Rule ruleIntervalMin = Rule { name = "over/above/at least/more than " , pattern = [ regex "над|поне|повече от" , financeWith TAmountOfMoney.value isJust ] , prod = \tokens -> case tokens of (_: Token AmountOfMoney (AmountOfMoneyData {TAmountOfMoney.value = Just to, TAmountOfMoney.currency = c}): _) -> Just . Token AmountOfMoney . withMin to $ currencyOnly c _ -> Nothing } rules :: [Rule] rules = [ ruleBGN , ruleDollar , ruleCent , ruleEUR , ruleIntersect , ruleIntersectAndNumeral , ruleIntersectAndXCents , ruleIntersectXCents , ruleIntervalBetweenNumeral , ruleIntervalBetween , ruleIntervalMax , ruleIntervalMin , ruleIntervalNumeralDash , ruleIntervalDash , rulePounds , rulePrecision ]