Skip to content

Commit

Permalink
Complete basic parsing of data file
Browse files Browse the repository at this point in the history
  • Loading branch information
rexcfnghk committed Jun 7, 2024
1 parent 42190d7 commit eeb626f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 4 deletions.
1 change: 1 addition & 0 deletions DataParser.Console/Core.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ type Error =
| FileFormatNotFound of availableFormats: Set<FileFormat> * givenFormat : FileFormat
| DataFileNameFormatError of fileName: string
| UnexpectedFormatLine of string
| UnparsableValue of obj

let (<*>) f x =
match f, x with
Expand Down
32 changes: 30 additions & 2 deletions DataParser.Console/DataFiles.fs
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
module DataParser.Console.DataFiles

open System.Globalization
open System.IO
open System.Linq
open System.Text
open DataParser.Console.Core
open System.Text.RegularExpressions
open DataParser.Console.FormatFiles

type DataFileName = DataFileName of fileFormat: FileFormat * rawDate : string
let [<Literal>] trueByteLiteral = 49uy
let [<Literal>] falseByteLiteral = 48uy

type DataFileName = DataFileName of fileFormat: FileFormat * rawDate : string

let lookupFileFormat availableFormats given =
if Set.contains given availableFormats
Expand All @@ -21,4 +28,25 @@ let parseDataFileName s =
if regexMatch.Success
then Ok <| DataFileName (FileFormat regexMatch.Groups[1].Value, regexMatch.Groups[2].Value)
else Error <| DataFileNameFormatError s


let parseDataFileLine (formatLines : FormatLine list) (dataFileLine : string) : Map<string, obj> =
let parseDataType dataType (s: byte array) : Result<obj, Error> =
match dataType with
| JBool -> if s = [|trueByteLiteral|] then Ok true elif s = [|falseByteLiteral|] then Ok false else Error (UnparsableValue s)
| JInt -> match System.Int32.TryParse (s, CultureInfo.InvariantCulture) with true, i -> Ok i | false, _ -> Error (UnparsableValue s)
| JString -> Ok <| let result = Encoding.UTF8.GetString s in result.Trim()

let folder (stream : MemoryStream, lineMaxCount, map) (FormatLine (columnName, width, dataType)) =
let byteArray = Array.create width 0uy
stream.ReadExactly(byteArray, 0, width)
let result = parseDataType dataType byteArray
stream, lineMaxCount, Map.add columnName result map

let bytes : byte array = Encoding.UTF8.GetBytes dataFileLine
use s = new MemoryStream(bytes)
let lineMaxCount = List.sumBy (fun (FormatLine (_, width, _)) -> width) formatLines
let _, _, map = List.fold folder (s, lineMaxCount, Map.empty) formatLines

map
|> Map.filter (fun _ -> Result.isOk)
|> Map.map (fun _ (Ok v) -> v)

Check warning on line 52 in DataParser.Console/DataFiles.fs

View workflow job for this annotation

GitHub Actions / build

Incomplete pattern matches on this expression. For example, the value 'Error (_)' may indicate a case not covered by the pattern(s).

Check warning on line 52 in DataParser.Console/DataFiles.fs

View workflow job for this annotation

GitHub Actions / build

Incomplete pattern matches on this expression. For example, the value 'Error (_)' may indicate a case not covered by the pattern(s).
1 change: 0 additions & 1 deletion DataParser.Console/FileRead.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module DataParser.Console.FileRead

open DataParser.Console.Core
open DataParser.Console.FormatFiles
open System.IO

Expand Down
27 changes: 26 additions & 1 deletion DataParser.Tests/Tests.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module DataParser.Tests.Main

open System
open System.Collections.Generic
open System.Globalization
open System.Text.RegularExpressions
open DataParser.Console.Core
Expand Down Expand Up @@ -108,4 +109,28 @@ let ``parseFormatFile returns expected FormatLines when there is one line`` form
let ``parseFormatFile returns expected FormatLines when there is two lines`` formatFile =
let expected = Ok [ FormatLine ("name", 10, JsonDataType.JString); FormatLine ("valid", 1, JsonDataType.JBool) ]

parseFormatFile formatFile =! expected
parseFormatFile formatFile =! expected

[<Xunit.Fact>]
let ``Given a format and a dataFileLine of Diabetes, parseDataFileLine returns an expected map`` () =
let dataFileLine = "Diabetes 1 1\n"
let formatLines = [
FormatLine ("name", 10, JsonDataType.JString)
FormatLine ("valid", 1, JsonDataType.JBool)
FormatLine("count", 3, JsonDataType.JInt)
]
let expected : Map<string, obj> = Map.ofList [ ("name", "Diabetes"); ("valid", true); ("count", 1) ]

parseDataFileLine formatLines dataFileLine =! expected

[<Xunit.Fact>]
let ``Given a format and a dataFileLine of Asthma, parseDataFileLine returns an expected map`` () =
let dataFileLine = "Asthma 0-14\n"
let formatLines = [
FormatLine ("name", 10, JsonDataType.JString)
FormatLine ("valid", 1, JsonDataType.JBool)
FormatLine("count", 3, JsonDataType.JInt)
]
let expected : Map<string, obj> = Map.ofList [ ("name", "Asthma"); ("valid", false); ("count", -14) ]

parseDataFileLine formatLines dataFileLine =! expected

0 comments on commit eeb626f

Please sign in to comment.