mirror of
https://github.com/Smaug123/WoofWare.Myriad
synced 2025-10-05 12:08:46 +00:00
Compare commits
2 Commits
WoofWare.M
...
WoofWare.M
Author | SHA1 | Date | |
---|---|---|---|
|
85929d49d5 | ||
|
db4694f6e7 |
8
.github/workflows/dotnet.yaml
vendored
8
.github/workflows/dotnet.yaml
vendored
@@ -236,7 +236,7 @@ jobs:
|
||||
name: nuget-package-attribute
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
|
||||
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -255,7 +255,7 @@ jobs:
|
||||
name: nuget-package-plugin
|
||||
path: packed
|
||||
- name: Attest Build Provenance
|
||||
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
|
||||
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
|
||||
with:
|
||||
subject-path: "packed/*.nupkg"
|
||||
|
||||
@@ -297,7 +297,7 @@ jobs:
|
||||
run: 'bash ./.github/workflows/assert-contents.sh'
|
||||
- name: Attest Build Provenance
|
||||
if: steps.publish-success.outputs.result == 'published'
|
||||
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
|
||||
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
|
||||
with:
|
||||
subject-path: "from-nuget.nupkg"
|
||||
|
||||
@@ -339,7 +339,7 @@ jobs:
|
||||
run: 'bash ./.github/workflows/assert-contents.sh'
|
||||
- name: Attest Build Provenance
|
||||
if: steps.publish-success.outputs.result == 'published'
|
||||
uses: actions/attest-build-provenance@897ed5eab6ed058a474202017ada7f40bfa52940 # v1.0.0
|
||||
uses: actions/attest-build-provenance@bdd51370e0416ac948727f861e03c2f05d32d78e # v1.3.2
|
||||
with:
|
||||
subject-path: "from-nuget.nupkg"
|
||||
|
||||
|
24
.gitignore
vendored
24
.gitignore
vendored
@@ -1,12 +1,12 @@
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
.idea/
|
||||
*.sln.DotSettings.user
|
||||
.DS_Store
|
||||
result
|
||||
.analyzerpackages/
|
||||
analysis.sarif
|
||||
.direnv/
|
||||
bin/
|
||||
obj/
|
||||
/packages/
|
||||
riderModule.iml
|
||||
/_ReSharper.Caches/
|
||||
.idea/
|
||||
*.sln.DotSettings.user
|
||||
.DS_Store
|
||||
result
|
||||
.analyzerpackages/
|
||||
analysis.sarif
|
||||
.direnv/
|
||||
|
@@ -1,5 +1,10 @@
|
||||
Notable changes are recorded here.
|
||||
|
||||
# WoofWare.Myriad.Plugins 2.1.45, WoofWare.Myriad.Plugins.Attributes 3.1.7
|
||||
|
||||
The NuGet packages are now attested to through [GitHub Attestations](https://github.blog/2024-05-02-introducing-artifact-attestations-now-in-public-beta/).
|
||||
You can run `gh attestation verify ~/.nuget/packages/woofware.myriad.plugins/2.1.45/woofware.myriad.plugins.2.1.45.nupkg -o Smaug123`, for example, to verify with GitHub that the GitHub Actions pipeline on this repository produced a nupkg file with the same hash as the one you were served from NuGet.
|
||||
|
||||
# WoofWare.Myriad.Plugins 2.1.33
|
||||
|
||||
`JsonParse` can now deserialize the discriminated unions which `JsonSerialize` wrote out.
|
||||
|
@@ -148,6 +148,7 @@ module GymLocation =
|
||||
reraise ()
|
||||
else
|
||||
reraise ()
|
||||
|> LanguagePrimitives.FloatWithMeasure
|
||||
|
||||
let arg_0 =
|
||||
try
|
||||
|
@@ -19,13 +19,16 @@ type GymAccessOptions =
|
||||
QrCodeAccess : bool
|
||||
}
|
||||
|
||||
[<Measure>]
|
||||
type measure
|
||||
|
||||
[<WoofWare.Myriad.Plugins.JsonParse>]
|
||||
type GymLocation =
|
||||
{
|
||||
[<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>]
|
||||
Longitude : float
|
||||
[<JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)>]
|
||||
Latitude : float
|
||||
Latitude : float<measure>
|
||||
}
|
||||
|
||||
[<WoofWare.Myriad.Plugins.JsonParse>]
|
||||
|
@@ -58,7 +58,7 @@ module PureGymDtos =
|
||||
[
|
||||
"""{"latitude": 1.0, "longitude": 3.0}""",
|
||||
{
|
||||
GymLocation.Latitude = 1.0
|
||||
GymLocation.Latitude = 1.0<measure>
|
||||
Longitude = 3.0
|
||||
}
|
||||
]
|
||||
@@ -96,7 +96,7 @@ module PureGymDtos =
|
||||
Location =
|
||||
{
|
||||
Longitude = -0.110252
|
||||
Latitude = 51.480401
|
||||
Latitude = 51.480401<measure>
|
||||
}
|
||||
TimeZone = "Europe/London"
|
||||
ReopenDate = "2021-04-12T00:00:00+01 Europe/London"
|
||||
|
@@ -140,6 +140,47 @@ module internal JsonParseGenerator =
|
||||
failwithf
|
||||
$"Unable to parse the key type %+A{desiredType} of a JSON object. Keys are strings, and this plugin does not know how to convert to that from a string."
|
||||
|
||||
let private parseNumberType
|
||||
(options : JsonParseOption)
|
||||
(propertyName : SynExpr option)
|
||||
(node : SynExpr)
|
||||
(typeName : string)
|
||||
=
|
||||
let basic = asValueGetValue propertyName typeName node
|
||||
|
||||
match options.JsonNumberHandlingArg with
|
||||
| None -> basic
|
||||
| Some option ->
|
||||
let cond =
|
||||
SynExpr.DotGet (SynExpr.createIdent "exc", range0, SynLongIdent.createS "Message", range0)
|
||||
|> SynExpr.callMethodArg "Contains" (SynExpr.CreateConst "cannot be converted to")
|
||||
|
||||
let handler =
|
||||
asValueGetValue propertyName "string" node
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent' (parseFunction typeName))
|
||||
|> SynExpr.ifThenElse
|
||||
(SynExpr.equals
|
||||
option
|
||||
(SynExpr.createLongIdent
|
||||
[
|
||||
"System"
|
||||
"Text"
|
||||
"Json"
|
||||
"Serialization"
|
||||
"JsonNumberHandling"
|
||||
"AllowReadingFromString"
|
||||
]))
|
||||
SynExpr.reraise
|
||||
|> SynExpr.ifThenElse cond SynExpr.reraise
|
||||
|
||||
basic
|
||||
|> SynExpr.pipeThroughTryWith
|
||||
(SynPat.IsInst (
|
||||
SynType.LongIdent (SynLongIdent.createS' [ "System" ; "InvalidOperationException" ]),
|
||||
range0
|
||||
))
|
||||
handler
|
||||
|
||||
/// Given `node.["town"]`, for example, choose how to obtain a JSON value from it.
|
||||
/// The property name is used in error messages at runtime to show where a JSON
|
||||
/// parse error occurred; supply `None` to indicate "don't validate".
|
||||
@@ -168,41 +209,7 @@ module internal JsonParseGenerator =
|
||||
node
|
||||
|> asValueGetValue propertyName "string"
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent [ "System" ; "DateTime" ; "Parse" ])
|
||||
| NumberType typeName ->
|
||||
let basic = asValueGetValue propertyName typeName node
|
||||
|
||||
match options.JsonNumberHandlingArg with
|
||||
| None -> basic
|
||||
| Some option ->
|
||||
let cond =
|
||||
SynExpr.DotGet (SynExpr.createIdent "exc", range0, SynLongIdent.createS "Message", range0)
|
||||
|> SynExpr.callMethodArg "Contains" (SynExpr.CreateConst "cannot be converted to")
|
||||
|
||||
let handler =
|
||||
asValueGetValue propertyName "string" node
|
||||
|> SynExpr.pipeThroughFunction (SynExpr.createLongIdent' (parseFunction typeName))
|
||||
|> SynExpr.ifThenElse
|
||||
(SynExpr.equals
|
||||
option
|
||||
(SynExpr.createLongIdent
|
||||
[
|
||||
"System"
|
||||
"Text"
|
||||
"Json"
|
||||
"Serialization"
|
||||
"JsonNumberHandling"
|
||||
"AllowReadingFromString"
|
||||
]))
|
||||
SynExpr.reraise
|
||||
|> SynExpr.ifThenElse cond SynExpr.reraise
|
||||
|
||||
basic
|
||||
|> SynExpr.pipeThroughTryWith
|
||||
(SynPat.IsInst (
|
||||
SynType.LongIdent (SynLongIdent.createS' [ "System" ; "InvalidOperationException" ]),
|
||||
range0
|
||||
))
|
||||
handler
|
||||
| NumberType typeName -> parseNumberType options propertyName node typeName
|
||||
| PrimitiveType typeName -> asValueGetValueIdent propertyName typeName node
|
||||
| OptionType ty ->
|
||||
parseNode None options ty (SynExpr.createIdent "v")
|
||||
@@ -261,6 +268,14 @@ module internal JsonParseGenerator =
|
||||
|> SynExpr.callMethod "ToJsonString"
|
||||
|> SynExpr.paren
|
||||
|> SynExpr.applyFunction (SynExpr.createLongIdent [ "System" ; "Numerics" ; "BigInteger" ; "Parse" ])
|
||||
| Measure (_measure, primType) ->
|
||||
let qualified =
|
||||
match Primitives.qualifyType primType with
|
||||
| None -> failwith $"did not recognise type %s{primType} to assign measure"
|
||||
| Some t -> t
|
||||
|
||||
parseNumberType options propertyName node primType
|
||||
|> SynExpr.pipeThroughFunction (Measure.getLanguagePrimitivesMeasure qualified)
|
||||
| _ ->
|
||||
// Let's just hope that we've also got our own type annotation!
|
||||
let typeName =
|
||||
|
24
WoofWare.Myriad.Plugins/Measure.fs
Normal file
24
WoofWare.Myriad.Plugins/Measure.fs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace WoofWare.Myriad.Plugins
|
||||
|
||||
open Fantomas.FCS.Syntax
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module internal Measure =
|
||||
|
||||
let getLanguagePrimitivesMeasure (typeName : LongIdent) : SynExpr =
|
||||
match typeName |> List.map _.idText with
|
||||
| [ "System" ; "Single" ] -> [ "LanguagePrimitives" ; "Float32WithMeasure" ]
|
||||
| [ "System" ; "Double" ] -> [ "LanguagePrimitives" ; "FloatWithMeasure" ]
|
||||
| [ "System" ; "Byte" ] -> [ "LanguagePrimitives" ; "ByteWithMeasure" ]
|
||||
| [ "System" ; "SByte" ] -> [ "LanguagePrimitives" ; "SByteWithMeasure" ]
|
||||
| [ "System" ; "Int16" ] -> [ "LanguagePrimitives" ; "Int16WithMeasure" ]
|
||||
| [ "System" ; "Int32" ] -> [ "LanguagePrimitives" ; "Int32WithMeasure" ]
|
||||
| [ "System" ; "Int64" ] -> [ "LanguagePrimitives" ; "Int64WithMeasure" ]
|
||||
| [ "System" ; "UInt16" ] -> [ "LanguagePrimitives" ; "UInt16WithMeasure" ]
|
||||
| [ "System" ; "UInt32" ] -> [ "LanguagePrimitives" ; "UInt32WithMeasure" ]
|
||||
| [ "System" ; "UInt64" ] -> [ "LanguagePrimitives" ; "UInt64WithMeasure" ]
|
||||
| l ->
|
||||
let l = String.concat "." l
|
||||
failwith $"unrecognised type for measure: %s{l}"
|
||||
|
||||
|> SynExpr.createLongIdent
|
@@ -87,6 +87,20 @@ module internal SynExpr =
|
||||
)
|
||||
|> applyTo b
|
||||
|
||||
/// {a} * {b}
|
||||
let times (a : SynExpr) (b : SynExpr) =
|
||||
SynExpr.CreateAppInfix (
|
||||
SynExpr.CreateLongIdent (
|
||||
SynLongIdent.SynLongIdent (
|
||||
Ident.CreateLong "op_Multiply",
|
||||
[],
|
||||
[ Some (IdentTrivia.OriginalNotation "*") ]
|
||||
)
|
||||
),
|
||||
a
|
||||
)
|
||||
|> applyTo b
|
||||
|
||||
let rec stripOptionalParen (expr : SynExpr) : SynExpr =
|
||||
match expr with
|
||||
| SynExpr.Paren (expr, _, _, _) -> stripOptionalParen expr
|
||||
|
@@ -197,6 +197,17 @@ module internal SynTypePatterns =
|
||||
| _ -> None
|
||||
| _ -> None
|
||||
|
||||
let (|Measure|_|) (fieldType : SynType) : (Ident * string) option =
|
||||
match fieldType with
|
||||
| SynType.App (NumberType outer,
|
||||
_,
|
||||
[ SynType.LongIdent (SynLongIdent.SynLongIdent ([ ident ], _, _)) ],
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_) -> Some (ident, outer)
|
||||
| _ -> None
|
||||
|
||||
let (|DateOnly|_|) (fieldType : SynType) =
|
||||
match fieldType with
|
||||
| SynType.LongIdent (SynLongIdent.SynLongIdent (ident, _, _)) ->
|
||||
|
@@ -46,6 +46,7 @@
|
||||
<Compile Include="SynExpr\SynAttribute.fs" />
|
||||
<Compile Include="SynExpr\SynModuleDecl.fs" />
|
||||
<Compile Include="SynExpr\SynModuleOrNamespace.fs" />
|
||||
<Compile Include="Measure.fs" />
|
||||
<Compile Include="AstHelper.fs" />
|
||||
<Compile Include="RemoveOptionsGenerator.fs"/>
|
||||
<Compile Include="InterfaceMockGenerator.fs"/>
|
||||
|
Reference in New Issue
Block a user