|
3 | 3 | using SoftwareOne.Rql.Abstractions.Argument.Pointer; |
4 | 4 | using SoftwareOne.Rql.Abstractions.Result; |
5 | 5 | using SoftwareOne.Rql.Linq.Core.Metadata; |
6 | | -using SoftwareOne.Rql.Linq.Core.Result; |
7 | 6 | using SoftwareOne.Rql.Linq.Services.Context; |
8 | 7 | using System.Linq.Expressions; |
9 | 8 |
|
10 | | -namespace SoftwareOne.Rql.Linq.Core |
| 9 | +namespace SoftwareOne.Rql.Linq.Core; |
| 10 | + |
| 11 | +internal abstract class PathInfoBuilder : IPathInfoBuilder |
11 | 12 | { |
12 | | - internal abstract class PathInfoBuilder : IPathInfoBuilder |
13 | | - { |
14 | | - private readonly IMetadataProvider _metadataProvider; |
15 | | - private readonly IBuilderContext _builderContext; |
| 13 | + private readonly IMetadataProvider _metadataProvider; |
| 14 | + private readonly IBuilderContext _builderContext; |
16 | 15 |
|
17 | | - protected PathInfoBuilder(IMetadataProvider metadataProvider, IBuilderContext builderContext) |
18 | | - { |
19 | | - _metadataProvider = metadataProvider; |
20 | | - _builderContext = builderContext; |
21 | | - } |
| 16 | + protected PathInfoBuilder(IMetadataProvider metadataProvider, IBuilderContext builderContext) |
| 17 | + { |
| 18 | + _metadataProvider = metadataProvider; |
| 19 | + _builderContext = builderContext; |
| 20 | + } |
22 | 21 |
|
23 | | - public Result<MemberPathInfo> Build(Expression root, RqlExpression rqlExpression) |
| 22 | + public Result<MemberPathInfo> Build(Expression root, RqlExpression rqlExpression) |
| 23 | + { |
| 24 | + switch (rqlExpression) |
24 | 25 | { |
25 | | - switch (rqlExpression) |
26 | | - { |
27 | | - case RqlSelf self: |
28 | | - { |
29 | | - if (self.Inner != null) |
30 | | - return Build(root, self.Inner); |
31 | | - |
32 | | - var path = string.Empty; |
33 | | - return new MemberPathInfo(path, path.AsMemory(0, 0), RqlPropertyInfo.Root, root); |
34 | | - } |
35 | | - case RqlConstant constant: |
36 | | - { |
37 | | - var path = Build(root, constant.Value); |
38 | | - if (path.IsError) |
39 | | - return path.Errors; |
40 | | - return path.Value!; |
41 | | - } |
42 | | - default: |
43 | | - return Error.Validation("Unsupported property node."); |
44 | | - } |
45 | | - } |
| 26 | + case RqlSelf self: |
| 27 | + { |
| 28 | + if (self.Inner != null) |
| 29 | + return Build(root, self.Inner); |
46 | 30 |
|
47 | | - public Result<MemberPathInfo> Build(Expression root, string path) |
48 | | - { |
49 | | - var nameSegments = path.Split('.'); |
50 | | - var aggregatedInfo = nameSegments.Aggregate( |
51 | | - new Result<MemberPathInfo>(new MemberPathInfo(path, path.AsMemory(0, 0), null!, root)), |
52 | | - (current, segment) => |
| 31 | + var path = string.Empty; |
| 32 | + return new MemberPathInfo(path, path.AsMemory(0, 0), RqlPropertyInfo.Root, root); |
| 33 | + } |
| 34 | + case RqlConstant constant: |
53 | 35 | { |
54 | | - if (current.IsError) |
55 | | - return current; |
| 36 | + var path = Build(root, constant.Value); |
| 37 | + if (path.IsError) |
| 38 | + return path.Errors; |
| 39 | + return path.Value!; |
| 40 | + } |
| 41 | + default: |
| 42 | + return Error.Validation("Unsupported property node."); |
| 43 | + } |
| 44 | + } |
56 | 45 |
|
57 | | - var previousLength = current.Value!.Path.Length; |
58 | | - var cumulativePath = current.Value.FullPath.AsMemory(0, (previousLength > 0 ? previousLength + 1 : previousLength) + segment.Length); |
| 46 | + public Result<MemberPathInfo> Build(Expression root, string path) |
| 47 | + { |
| 48 | + var nameSegments = path.Split('.'); |
| 49 | + var aggregatedInfo = nameSegments.Aggregate( |
| 50 | + new Result<MemberPathInfo>(new MemberPathInfo(path, path.AsMemory(0, 0), null!, root)), |
| 51 | + (current, segment) => |
| 52 | + { |
| 53 | + if (current.IsError) |
| 54 | + return current; |
59 | 55 |
|
60 | | - if (!_metadataProvider.TryGetPropertyByDisplayName(current.Value.Expression.Type, segment, out var propInfo) || propInfo!.IsIgnored) |
61 | | - return Error.Validation("Invalid property path.", _builderContext.GetFullPath(cumulativePath.ToString())); |
| 56 | + var previousLength = current.Value!.Path.Length; |
| 57 | + var cumulativePath = current.Value.FullPath.AsMemory(0, (previousLength > 0 ? previousLength + 1 : previousLength) + segment.Length); |
62 | 58 |
|
63 | | - var expression = (Expression)Expression.MakeMemberAccess(current.Value!.Expression, propInfo!.Property!); |
64 | | - var pathInfo = new MemberPathInfo(current.Value.FullPath, cumulativePath, propInfo, expression); |
| 59 | + if (!_metadataProvider.TryGetPropertyByDisplayName(current.Value.Expression.Type, segment, out var propInfo) || propInfo!.IsIgnored) |
| 60 | + return Error.Validation("Invalid property path.", _builderContext.GetFullPath(cumulativePath.ToString())); |
65 | 61 |
|
66 | | - var validationResult = ValidatePath(pathInfo); |
| 62 | + var expression = (Expression)Expression.MakeMemberAccess(current.Value!.Expression, propInfo!.Property!); |
| 63 | + var pathInfo = new MemberPathInfo(current.Value.FullPath, cumulativePath, propInfo, expression); |
67 | 64 |
|
68 | | - if (validationResult.IsError) |
69 | | - return validationResult.Errors; |
| 65 | + var validationResult = ValidatePath(pathInfo); |
70 | 66 |
|
71 | | - return pathInfo; |
72 | | - }); |
| 67 | + if (validationResult.IsError) |
| 68 | + return validationResult.Errors; |
73 | 69 |
|
74 | | - if (aggregatedInfo.IsError) |
75 | | - return aggregatedInfo.Errors; |
| 70 | + return pathInfo; |
| 71 | + }); |
76 | 72 |
|
77 | | - return aggregatedInfo.Value!; |
78 | | - } |
| 73 | + if (aggregatedInfo.IsError) |
| 74 | + return aggregatedInfo.Errors; |
79 | 75 |
|
80 | | - protected abstract Result<bool> ValidatePath(MemberPathInfo pathInfo); |
| 76 | + return aggregatedInfo.Value!; |
81 | 77 | } |
| 78 | + |
| 79 | + protected abstract Result<bool> ValidatePath(MemberPathInfo pathInfo); |
82 | 80 | } |
0 commit comments