Skip to content

Commit

Permalink
14 getin (#15)
Browse files Browse the repository at this point in the history
* implments GetIn

* pump version to 0.4.0

* update doc

close #14
  • Loading branch information
robertluo authored Aug 8, 2019
1 parent d57f4f4 commit ae6dd09
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 6 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ My attempt of implementing [Edn format](https://github.com/edn-format/edn) for .

## Usage

### Parse

```F#
open Robertluo
Expand All @@ -28,9 +30,21 @@ var b = Edn.VecOf(new Edn[] { Edn.Kw("foo", "bar"), Edn.NewEBool(false), Edn.New
var b = Edn.Parse("[:foo/bar, false, \"Hello\"]");
```

### GetIn

`GetIn` can quickly pull value from a EDN value.

```c#
/// Get in can
var c = Edn.Parse("[{:a 3 :b \"ok\"} {:a 15, :b nil}]");
WriteLine($"Get in: {c.GetIn(new Edn[] {Edn.NewEInteger(1L), Edn.Kw(null, "a")})}");
```

## Releases

- 0.2.0 with all standard features implemented
- 0.3.0 with some constructor for c# programmer convinience
- 0.4.0 introduce `GetIn`

## Design

Expand Down
2 changes: 1 addition & 1 deletion src/Edn.Net/Edn.Net.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>Robertluo.Edn</PackageId>
<version>0.3.0</version>
<version>0.4.0</version>
</PropertyGroup>
<ItemGroup>
<Compile Include="Library.fs" />
Expand Down
25 changes: 25 additions & 0 deletions src/Edn.Net/Library.fs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,30 @@ module Edn =
esymbol; estring; etagged ] .>> ws

//-------------- Interface ---------------
/// Parse a string into a Edn value
let parse = run evalue

/// Get value from edn on path
let rec getIn (path : Edn list) (edn : Edn) : Edn =
match edn with
| EVector v ->
match path with
| [] -> edn
| x :: xs ->
match x with
| EInteger i -> v.GetValue i :?> Edn |> getIn xs
| _ -> failwith "vector can only support integer path"
| EMap m ->
match path with
| [] -> edn
| x :: xs -> Map.find x m |> getIn xs
| v ->
match path with
| [] -> edn
| _ :: _ ->
invalidOp
(sprintf "Edn v (%s) does not support GetIn" (v.ToString()))

//-------------- Attach functions to type --------------
exception ParseException of string * ParserError

Expand All @@ -212,6 +234,9 @@ type Edn with
Name = sym }
|> EKeyword

/// Get value specified by path
member this.GetIn(path) = Edn.getIn (List.ofArray path) this

/// Shortcut for creating EVector from an array
static member VecOf(elems) = EVector elems

Expand Down
11 changes: 7 additions & 4 deletions src/Trial/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ static void Main(string[] args)
{
var v = Edn.Parse("{:foo/bar 35 :name \"Hello\"}");
var u = v.IsEMap ? ((Edn.EMap) v).Item : null;

var a = Edn.MapOf(new Tuple<Edn, Edn>[] {new Tuple<Edn, Edn>(Edn.Kw(null, "foo"), Edn.NewEInteger(3L))});
WriteLine($"a should be: {a}");
WriteLine($"equals to: {Edn.Parse("{:foo 3}")}");
var b = Edn.VecOf(new Edn[] { Edn.Kw("foo", "bar"), Edn.NewEBool(false), Edn.NewEString("hello")});

var b = Edn.VecOf(new Edn[] {Edn.Kw("foo", "bar"), Edn.NewEBool(false), Edn.NewEString("hello")});
WriteLine($"b should be: {b}");
WriteLine($"equals to: {Edn.Parse("[:foo/bar, false, \"hello\"]")}");

var c = Edn.Parse("[{:a 3 :b \"ok\"} {:a 15, :b nil}]");
WriteLine($"Get in: {c.GetIn(new Edn[] {Edn.NewEInteger(1L), Edn.Kw(null, "a")})}");
}
}
}
}
16 changes: 15 additions & 1 deletion test/Edn.Net.Test/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ let tests =
| v -> failtestf "not understandable: %A" v ]

[<Tests>]
let test2 =
let testToString =
testList "ToString"
[ testCase "keyword" <| fun _ ->
let input =
Expand Down Expand Up @@ -125,4 +125,18 @@ let testMisc =
<| fun _ ->
let input = "[3:foo"
Expect.throws (fun () -> (Edn.Parse input) |> ignore)
"should throw"

testCase "when get in a valid value"
<| fun _ ->
let input = Edn.Parse "[{:a 3 :b true} {:a 5 :b false}]"
Expect.equal (Edn.getIn [ EInteger 1L
Edn.Kw(null, "a") ] input) (EInteger 5L)
"should find value"

testCase "when specify an invalid path"
<| fun _ ->
let input = Edn.Parse "[[1 \"ok\"]]"
Expect.throws
(fun () -> Edn.getIn [ EInteger 2L ] input |> ignore)
"should throw" ]

0 comments on commit ae6dd09

Please sign in to comment.