Skip to content

Instantly share code, notes, and snippets.

@ykon
Created February 3, 2019 12:13
Show Gist options
  • Save ykon/241b7e8d8b981eaf86bb1429e334188d to your computer and use it in GitHub Desktop.
Save ykon/241b7e8d8b981eaf86bb1429e334188d to your computer and use it in GitHub Desktop.
open System
open System.IO
open System.Text.RegularExpressions
let read_file (path:string): string option =
if (File.Exists path) then Some(File.ReadAllText path) else None
let split_header_body (text:string): (string*string) option =
match text.Split([|"\r\n\r\n"|], 2, StringSplitOptions.None) with
| [| header; body|] -> Some(header, body)
| _ -> None
let unfold_header (header:string): string =
Regex.Replace(header, "\r\n[ \t]+", " ")
let split_field (line:string): (string*string) option =
let m = Regex.Match(line, "(\S+): *(.+)?")
if m.Success then Some((m.Groups.[1].Value, m.Groups.[2].Value)) else None
let parse_header (header:string): (string*string)[] =
header.Split([|"\r\n"|], StringSplitOptions.None)
|> Array.choose split_field
let tuple_to_hash (header:(string*string) array): Map<string, string[]> =
header
|> Array.groupBy fst
|> Array.map (fun (k, v) -> k.ToLower(), v |> Array.map snd)
|> Map.ofArray
[<EntryPoint>]
let main _ =
let mail_header =
read_file "data.txt" |> Option.defaultWith (fun () -> failwith "File not found")
|> split_header_body |> Option.defaultWith (fun () -> failwith "Invalid mail-header")
|> fst
|> unfold_header
|> parse_header
|> tuple_to_hash
printfn "%A" mail_header
Console.Read() |> ignore
0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment