Skip to content

Commit 7203638

Browse files
committed
merge main
Signed-off-by: Johannes Tuerk <johannes.tuerk@lissi.id>
2 parents c91adcb + 2605ff0 commit 7203638

File tree

108 files changed

+3010
-1494
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+3010
-1494
lines changed

.github/workflows/publish-nuget.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ jobs:
5757

5858
- name: Run tests
5959
run: |
60+
dotnet test test/WalletFramework.Core.Tests --configuration $BUILD_CONFIG --no-restore --no-build
61+
dotnet test test/WalletFramework.MdocLib.Tests --configuration $BUILD_CONFIG --no-restore --no-build
62+
dotnet test test/WalletFramework.MdocVc.Tests --configuration $BUILD_CONFIG --no-restore --no-build
6063
dotnet test test/WalletFramework.Oid4Vc.Tests --configuration $BUILD_CONFIG --no-restore --no-build
6164
dotnet test test/WalletFramework.SdJwtVc.Tests --configuration $BUILD_CONFIG --no-restore --no-build
6265

src/WalletFramework.Core.Tests/Path/ClaimPathTests.cs

Lines changed: 0 additions & 42 deletions
This file was deleted.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using WalletFramework.Core.ClaimPaths.Errors;
2+
using WalletFramework.Core.Functional;
3+
using WalletFramework.Core.Path;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace WalletFramework.Core.ClaimPaths;
7+
8+
public readonly struct ClaimPath
9+
{
10+
private readonly IReadOnlyList<ClaimPathComponent> _components;
11+
12+
private ClaimPath(IReadOnlyList<ClaimPathComponent> components)
13+
{
14+
_components = components;
15+
}
16+
17+
public IReadOnlyList<ClaimPathComponent> GetPathComponents() => _components;
18+
19+
public static Validation<ClaimPath> FromComponents(IEnumerable<ClaimPathComponent> components)
20+
{
21+
var list = components.ToList();
22+
if (list.Count == 0)
23+
return new ClaimPathIsEmptyError();
24+
return new ClaimPath(list);
25+
}
26+
27+
public static Validation<ClaimPath> FromJArray(JArray array)
28+
{
29+
return
30+
from components in array.TraverseAll(ClaimPathComponent.Create)
31+
from path in FromComponents(components)
32+
select path;
33+
}
34+
}
35+
36+
public static class ClaimPathFun
37+
{
38+
public static JsonPath ToJsonPath(this ClaimPath claimPath)
39+
{
40+
var jsonPath = "$." + string.Join('.', claimPath.GetPathComponents().Select(x =>
41+
{
42+
if (x.IsKey) return x.AsKey();
43+
if (x.IsIndex) return x.AsIndex()?.ToString();
44+
return null;
45+
}).Where(x => x is not null));
46+
return JsonPath.ValidJsonPath(jsonPath).UnwrapOrThrow();
47+
}
48+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using WalletFramework.Core.ClaimPaths.Errors;
2+
using WalletFramework.Core.Functional;
3+
using OneOf;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace WalletFramework.Core.ClaimPaths;
7+
8+
public sealed record ClaimPathComponent
9+
{
10+
private readonly OneOf<string, int, SelectAllElementsInArrayComponent> _value;
11+
12+
private ClaimPathComponent(OneOf<string, int, SelectAllElementsInArrayComponent> value) => _value = value;
13+
14+
public static Validation<ClaimPathComponent> Create(JToken token) =>
15+
token.Type switch
16+
{
17+
JTokenType.String => !string.IsNullOrEmpty(token.Value<string>())
18+
? new ClaimPathComponent(token.Value<string>()!)
19+
: new UnknownComponentError(),
20+
JTokenType.Integer => new ClaimPathComponent(token.Value<int>()),
21+
JTokenType.Null => new ClaimPathComponent(new SelectAllElementsInArrayComponent()),
22+
_ => new UnknownComponentError()
23+
};
24+
25+
public T Match<T>(
26+
Func<string, T> onKey,
27+
Func<int, T> onIndex,
28+
Func<SelectAllElementsInArrayComponent, T> onSelectAll) =>
29+
_value.Match(onKey, onIndex, onSelectAll);
30+
31+
public bool IsKey => _value.IsT0;
32+
33+
public bool IsIndex => _value.IsT1;
34+
35+
public string? AsKey() => _value.TryPickT0(out var key, out _) ? key : null;
36+
37+
public int? AsIndex() => _value.TryPickT1(out var idx, out _) ? idx : null;
38+
39+
public override string ToString()
40+
{
41+
return _value.Match(
42+
key => key,
43+
index => index.ToString(),
44+
selectAll => selectAll.ToString());
45+
}
46+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using Newtonsoft.Json;
2+
using Newtonsoft.Json.Linq;
3+
using WalletFramework.Core.Functional;
4+
5+
namespace WalletFramework.Core.ClaimPaths;
6+
7+
public class ClaimPathJsonConverter : JsonConverter<ClaimPath>
8+
{
9+
public override bool CanWrite => true;
10+
11+
public override void WriteJson(JsonWriter writer, ClaimPath value, JsonSerializer serializer)
12+
{
13+
writer.WriteStartArray();
14+
foreach (var component in value.GetPathComponents())
15+
{
16+
component.Match(
17+
onKey: k => { writer.WriteValue(k); return 0; },
18+
onIndex: i => { writer.WriteValue(i); return 0; },
19+
onSelectAll: _ => { writer.WriteNull(); return 0; }
20+
);
21+
}
22+
writer.WriteEndArray();
23+
}
24+
25+
public override ClaimPath ReadJson(JsonReader reader, Type objectType, ClaimPath existingValue, bool hasExistingValue, JsonSerializer serializer)
26+
{
27+
var array = JArray.Load(reader);
28+
var validation = ClaimPath.FromJArray(array);
29+
return validation.UnwrapOrThrow();
30+
}
31+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using Newtonsoft.Json.Linq;
2+
using WalletFramework.Core.Functional;
3+
using WalletFramework.Core.ClaimPaths.Errors;
4+
5+
namespace WalletFramework.Core.ClaimPaths;
6+
7+
public record ClaimPathSelection
8+
{
9+
private ClaimPathSelection(IEnumerable<JToken> values) => Values = values;
10+
11+
private IEnumerable<JToken> Values { get; }
12+
13+
public IEnumerable<JToken> GetValues() => Values;
14+
15+
public static Validation<ClaimPathSelection> Create(IEnumerable<JToken> values)
16+
{
17+
var arr = values as JToken[] ?? [.. values];
18+
return arr.Any() ? new ClaimPathSelection(arr) : new SelectionIsEmptyError();
19+
}
20+
}
21+
22+
public static class ClaimPathSelectionFun
23+
{
24+
public static Validation<ClaimPathSelection> SelectObjectKey(ClaimPathSelection selection, string key)
25+
{
26+
if (selection.GetValues().Any(token => token is not JObject))
27+
return new SelectedElementIsNotAnObjectError();
28+
29+
var newSelection = selection
30+
.GetValues()
31+
.Cast<JObject>()
32+
.SelectMany(obj => obj.TryGetValue(key, out var value)
33+
? [value]
34+
: Array.Empty<JToken>());
35+
36+
return ClaimPathSelection.Create(newSelection);
37+
}
38+
39+
public static Validation<ClaimPathSelection> SelectArrayIndex(ClaimPathSelection selection, int index)
40+
{
41+
if (selection.GetValues().Any(token => token is not JArray))
42+
return new SelectedElementIsNotAnArrayError();
43+
44+
var arrays = selection.GetValues().Cast<JArray>().ToArray();
45+
if (arrays.Any(array => index < 0 || index >= array.Count))
46+
return new SelectedElementDoesNotExistInArrayError();
47+
48+
var newSelection = arrays.Select(array => array[index]);
49+
return ClaimPathSelection.Create(newSelection);
50+
}
51+
52+
public static Validation<ClaimPathSelection> SelectAllArrayElements(ClaimPathSelection selection)
53+
{
54+
if (selection.GetValues().Any(token => token is not JArray))
55+
return new SelectedElementIsNotAnArrayError();
56+
57+
var newSelection = selection
58+
.GetValues()
59+
.Cast<JArray>()
60+
.SelectMany(array => array.Children());
61+
62+
return ClaimPathSelection.Create(newSelection);
63+
}
64+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using WalletFramework.Core.Functional;
2+
3+
namespace WalletFramework.Core.ClaimPaths.Errors.Abstractions;
4+
5+
public abstract record ClaimPathError : Error
6+
{
7+
protected ClaimPathError(string message) : base(message)
8+
{
9+
}
10+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
using WalletFramework.Core.Functional;
2+
3+
namespace WalletFramework.Core.ClaimPaths.Errors;
4+
5+
public record ClaimPathIsEmptyError() : Error("ClaimPath is not allowed to be empty");
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using WalletFramework.Core.ClaimPaths.Errors.Abstractions;
2+
3+
namespace WalletFramework.Core.ClaimPaths.Errors;
4+
5+
public record ElementNotFoundError(string Namespace, string ElementId)
6+
: ClaimPathError($"The element '{ElementId}' was not found in the namespace '{Namespace}'.");
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
using WalletFramework.Core.ClaimPaths.Errors.Abstractions;
2+
3+
namespace WalletFramework.Core.ClaimPaths.Errors;
4+
5+
public record NamespaceNotFoundError(string Namespace)
6+
: ClaimPathError($"The namespace '{Namespace}' was not found in the document.");

0 commit comments

Comments
 (0)