allykzam / amazingant.fsharp.typeexpansion.templates Goto Github PK
View Code? Open in Web Editor NEWTemplates for use with the Amazingant.FSharp.TypeExpansion tool
License: MIT License
Templates for use with the Amazingant.FSharp.TypeExpansion tool
License: MIT License
Would like to be able to perform validation after a record type is processed from XML; will want to either settle on a function name and signature to look for, or add an attribute to denote validation functions.
Going to want this at some point, as it is already bothering me that it does not exist. Will likely ignore for the moment and try to work on this sometime in the next few weeks?
Although it eventually leads to a useful point in the expanded code, the exceptions thrown when a given XML document is not valid are...less than helpful? Would be nice to add some validation code to improve the messages that come out.
Need to wrap validation function names with backticks, so that they can have spaces in their names. Because I am a horrible person who puts spaces in function names.
Need to work up some sample XML files and test against them so that I can start playing with ideas for simplifying the generated code without breaking anything.
For each sub-directory under the tests
directory, the test
build target should:
Had a crazy idea quite some time ago for a template that builds a view model suitable for use with WPF bindings, and bases it on an immutable data model. Creating an issue here so that the current code can be placed in an appropriate branch.
Still just playing with an idea, documenting it here so I can come back and read this later to see if it sounds insane or not.
Initial thought, given the following sum type:
type SumType =
| OneOption of Value : int
| OtherOption of Text : string
Any of the following could be processed as OneOption(4)
:
<Thing>
<OneOption>4</OneOption>
</Thing>
<Thing>
<OneOption>
<Value>4</Value>
</OneOption>
</Thing>
<Thing>4</Thing>
And any of the following as OtherOption("Test")
:
<Thing>
<OtherOption>Test</OtherOption>
</Thing>
<Thing>
<OtherOption>
<Text>Test</Text>
</OtherOption>
</Thing>
<Thing>Test</Thing>
The first XML option in either set assumes that sum type cases will only ever contain a single field, and therefore the matching node's contents can be used. The sum type case names can then be matched as a node or attribute name as is currently done for product type fields with no attributes.
The second option is a bit strict, but would easily allow any number of fields so long as they had names. If the fields do not have names, perhaps we could fall back to the order of the fields and the order of the XML nodes? But that seems dangerous; it would be safer to disallow FromXml expansion on sum type cases with unnamed fields.
As with the first option, the final option also assumes that the sum type cases will only contain a single field. Instead of going by field name, this option would select the appropriate case based on which field can be successfully parsed. This also seems dangerous; what happens when one case contains a single integer field and the other contains a string? Putting a case with a string field near the beginning of the sum type declaration would cause that case to match before any of the others. Seems like this kind of support is better done by reminding myself that I can just add a static TryParse
function on sum types, although it would be nice to provide an easy way to allow "nested" FromXml-expanded types as fields in a sum type's cases.
As of version 1.2.1
, the FromXml
template ignored underscores in node and attribute names. This was missed in f804462, and has caused some regressions downstream. Need to fix and add tests for this.
Should use the incorrectly-named isUnionField
code from the lenses template
Testing with some data at work, and finding that an exception is thrown when trying to parse out an int option
from an empty node. Except this is exactly why I marked the field as optional. Need to adjust the behavior so that if the InnerText
property for a node is an empty string, the value is automatically None
if populating an optional field, otherwise I'll just end up marking these fields as string
and writing more code that this template is supposed to take away from me.
Should be easy enough to add some basic sample code for each template. Initial expectation is that for each template, there should be:
FromXml
template)With the above established, it should be possible to add a build target for testing which iterates through the test directories for each template and:
Noticed that I can build a record with a field named In
and another named Out
and that compiles fine, but in the generated code, the lower-cased names for these two fields, in
and out
respectively, are F# keywords and cannot be used directly. Temporary solution is to turn off the type provider and gratuitously sprinkle back-ticks everywhere until the compiler errors go away.
While working with the same XML sample that led to #14, got an exception stating Invalid value '' could not be parsed as a 'System.Int32'
. Notably missing from the message is any indication of which property it was trying to parse an int for.
Including a (Thing list) option
results in expanded code like this:
let ``field`` =
let xs = findAllNodes children "nodename"
|> Seq.toArray
if xs.Length = 0 then None
else xs |> Array.map Some.Type.Here.FromXmlNode |> Array.toList
When it should result in this:
let ``field`` =
let xs = findAllNodes children "nodename" |> Seq.toArray
if xs.Length = 0 then None
else xs |> Array.map Some.Type.Here.FromXmlNode |> Array.toList |> Some
Or, more aesthetically-pleasing:
let ``field`` =
let xs = Seq.toArray (findAllNodes children "nodename")
if xs.Length = 0
then None
else
xs
|> Array.map Some.Type.Here.FromXmlNode
|> Array.toList
|> Some
This appears to be the source.
Need to open Amazingant.FSharp.TypeExpansion.Templates.Lenses
for each module, and need to update the calls to makeStaticLens
-> MakeStaticLens
and compose
-> Compose
.
Would be nice to use the following XML and source type:
<Person>
<PhoneNumbers>
<Phone>123456789</Phone>
<Phone>987654321</Phone>
</PhoneNumbers>
...
</Person>
...
type Person =
{
[<XmlNode("PhoneNumbers/Phone")>]
PhoneNumbers : string list;
...
It may be worth creating a new attribute that can be used to just specify an XPath to follow?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.