summaryrefslogtreecommitdiff
path: root/elm3/Lib/Util.elm
blob: f6b39188d38f9f4cc8be1b02b9aca57da8604422 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Lib.Util exposing (..)

import Char
import Dict

-- Delete an element from a List
delidx : Int -> List a -> List a
delidx n l = List.take n l ++ List.drop (n+1) l


-- Modify an element in a List
modidx : Int -> (a -> a) -> List a -> List a
modidx n f = List.indexedMap (\i e -> if i == n then f e else e)


isJust : Maybe a -> Bool
isJust m = case m of
  Just _ -> True
  _      -> False


-- Split by newline, trim whitespace and remove empty lines
splitLn : String -> List String
splitLn = String.lines >> List.map String.trim >> List.filter ((/=)"")

-- Returns true if the list contains duplicates
hasDuplicates : List comparable -> Bool
hasDuplicates l =
  let
    step e acc =
      case acc of
        Nothing -> Nothing
        Just m -> if Dict.member e m then Nothing else Just (Dict.insert e True m)
  in
    case List.foldr step (Just Dict.empty) l of
      Nothing -> True
      Just _  -> False


-- Similar to perl's ucfirst() (not terribly efficient)
toUpperFirst : String -> String
toUpperFirst s = String.toList s |> List.indexedMap (\i c -> if i == 0 then Char.toUpper c else c) |> String.fromList


-- Haskell's 'lookup' - find an entry in an association list
lookup : a -> List (a,b) -> Maybe b
lookup n l = List.filter (\(a,_) -> a == n) l |> List.head |> Maybe.map Tuple.second


formatGtin : Int -> String
formatGtin n = if n == 0 then "" else String.fromInt n |> String.padLeft 12 '0'


-- Based on VNDBUtil::gtintype()
validateGtin : String -> Maybe Int
validateGtin =
  let check = String.fromInt
        >> String.reverse
        >> String.toList
        >> List.indexedMap (\i c -> (Char.toCode c - Char.toCode '0') * if modBy 2 i == 0 then 1 else 3)
        >> List.sum
      inval n =
            n <     1000000000
        || (n >=  200000000000 && n <  600000000000)
        || (n >= 2000000000000 && n < 3000000000000)
        ||  n >= 9770000000000
        || modBy 10 (check n) /= 0
  in String.filter Char.isDigit >> String.toInt >> Maybe.andThen (\n -> if inval n then Nothing else Just n)


spoilLevels : List (String, String)
spoilLevels =
  [ ("0", "No spoiler")
  , ("1", "Minor spoiler")
  , ("2", "Major spoiler")
  ]