Is there a way to parse XML with Purescript? - purescript

I'm looking into functional-programming ways to write a simple web app that does XSLT-like things. I'm thinking about trying Purescript, but I need to make sure it's possible (and relatively easy) to parse XML using it. Is there a way to do that? I found purescript-xml but it seems to be dead (no longer on Pursuit). Am I missing something?

I made a simple foreign import for DOMParser and then used the standard DOM library purescript-dom.
There are bindings in purescript-domparser but I didn't care for them. There is no reason I can discern for representing the DOMParser object.
This is what I used:
exports.parseXML = function (s) {
return new DOMParser().parseFromString(s, 'application/xml');
}
foreign import parseXML :: String -> Document
Unfortunately, DOMParser does not make it straight-forward to determine if parsing failed. On failure, it still returns a valid Document but only contains information about the error.

Related

Validating data using FirestoreDataConverter

Is it possible to do some kind of data validation when using FirestoreDataConverter<T>?
Looking at the call signature for fromFirestore, it seems like you can only return T. But what if I look at the data and realize that there is invalid data in the database? (I know, I should guard against that in the first place, but bad things happen.)
And it is even more important to guard against errors when using toFirestore. Again, is there a recommended way to do data validation before writing to the database?
I ask because looking at the VueFire documentation , they seem to return null on invalid data. Is that simply an error on their part?
I can see two options. Include some kind of error-state type in the signature (FirestoreDataConverter<T|E>) or throw an error. Is one or the other the 'recommended practice'?
I wish the official docs had more information on how to use FirestoreDataConverter.

Visual Studio Code Providers for language extension

I am trying to learn how to implement some of the helper providers: autocomplete, signature help and hover.
I am doing it for a framework that, as far as I know, it cannot be executed outside its main application, so one way I thought to go about this (get the objects types, methods and docs) is by parsing its documentation.
For example the Hover provider; once the cursor is hovering the word, I can search for it in the documentation and display the result:
class HSHoverProvider implements vscode.HoverProvider {
public provideSignatureHelp(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
): vscode.SignatureHelp {
// get current word/line under the cursor and find a match inside the docs
...
return new vscode.Hover(data);
}
}
...
context.subscriptions.push(
vscode.languages.registerHoverProvider("lua", new HSHoverProvider())
);
This works fine when the action is directly on the initial declaration. I can parse directly the line and find what I need with a regex.
-- hovering over `application`, I check the context with a regex.
local app = hs.application('Code')
However, I am having a hard time when it comes to a "reference". Searching the document for the declaration of app with a regex approach leads to many edge cases, mainly because of the declaration scope:
Example:
-- declaration target
local app = hs.application('Code')
local function foo()
local app = hs.pasteboard()
end
local function bar()
if 'foo' then
local app = hs.alert()
end
do local app = hs.window.focusedWindow() end
-- a regex will have a hard time to understand which declaration is correct
print(app:title())
end
This lead me thinking that a regex is not the appropriate solution. I also thought that implementing vscode.DefinitionProvider will give me some insight but it did not.
I've tried to look at other extensions that do already the same thing (mainly Lua Language Server by sumneko), but I am not able to understand how they went for it (besides they are using the language server approach).
How would I go for something like this? Do I need an AST tree and inspect from there? Would using the language server be a better choice? Am I missing a bigger picture or I just need a more robust document parser?
Any insight is appreciated. Thanks in advance
The usual approach in such cases is to create a symbol table. You start by parsing the code for which you want to provide the tooling. From the parse tree (or syntax tree, depending on the parser tool used) you generate your symbol table, which holds the informations you need, including the nesting of blocks and symbols, the type of symbols (e.g. object name or object reference) and the scope for which a symbol is valid.

make play-json read the empty string as None for a type of Option[T]

I'm attempting to parse json from the GitHub API with play-json, and encountering a problem with the merge_commit_sha field on Pull Requests (incidentally, I know this field is deprecated, but don't want to discuss that in this parsing problem!). Unfortunately merge_commit_sha field comes back as the empty string in some cases:
"merge_commit_sha": ""
This is how the field is declared in my case class:
merge_commit_sha: Option[ObjectId],
I have an implicit Format[ObjectId], which does not tolerate the empty string, because that's not a valid value for a Git hash id. I'm also using a play-json macro-generated Read[PullRequest], which I'd like to keep on using, in preference to individually declaring reads for every single field on pull requests.
As I've declared the field to be an Option, I'd like "merge_commit_sha": "" to be read as the value None, but this is not what currently happens - a string is present, so the Format[ObjectId] is invoked, and returns a JsFailure.
One thing I tried was declaring an implicit Format[Option[ObjectId]] with the required behaviour, but it didn't seem to get used by the macro-generated Read[PullRequest].
You can define a custom Reads and Writes yourself.
Using Json.format[MyType] uses a Scala macro. You may be able to hook into that. Although, 'extending' a macro for this one case class just seems wrong.
Custom Reads and Writes might be a little 'boilerplate-like' and boring, but they have their upsides.
For example if your json has a bunch of new fields on it, you wont get a JsError when validating or transforming it to a case class. You only take what you need from the JSON and create objects. It also allows for a separation between your internal model and what you're consuming, which in some cases is preferred.
I hope this helps,
Rhys
EDIT
After using some other JSON libs I may have found what you are looking for.
I know the question was asking specifically after Play JSON.
If you're able to move away from Play JSON, Look at spray-json-shapeless specifically JsNullBehaviour and JsNullNotNone REF.

Converting strings to other datatypes in Red

What is the recommended way to convert a string to an integer in Red?
One way I found is:
load "123"
== 123
Is load the best way of getting an integer from a string in Red?
Is there any danger in using load in this way specifically if the string is from an unvalidated source?
Currently, that is the only way, as to action has not been implemented yet. It is safe using load, as it does not do any kind of evaluation and the construction syntax support is very basic (covering just none and logic values).
EDIT: to action is now available from v0.6.2 on, so to-integer "123" can be used too.

What is to prefer in Restlet: handleGet, handlePost OR represent, acceptRepresetation?

IMHO, there are two techiques to handle a query for a resource:
For http GET you can override represent(Variant variant) or handleGet().
For http POST the same applies with acceptRepresentation(Representation entity) and handlePost().
The doc for handleGet says:
Handles a GET call by automatically returning the best representation available. The content negotiation is automatically supported based on the client's preferences available in the request. This feature can be turned off using the "negotiateContent" property.
and for represent:
Returns a full representation for a given variant previously returned via the getVariants() method. The default implementation directly returns the variant in case the variants are already full representations. In all other cases, you will need to override this method in order to provide your own implementation.
What are the main differences between these two types of implementations? In which case should I prefer one over the other? Is it right that I can achieve with e.g. handleGet() everything that would work with represent()?
I first started using handleGet setting the entity for the response. When I implemented another project I used represent. Looking back i can't really say one way is better or clearer than the other. What are your expirences for that?
I recommend using represent(Variant) because then you’ll be leveraging the content negotiation functionality provided by the default implementation of handleGet(Request, Response).
BTW, lately I've started using the annotation-based syntax instead of overriding superclass methods, and I like it. I find it clearer, simpler, and more flexible.
For example:
#Post('html')
Representation doSearch(Form form) throws ResourceException {
// get a field from the form
String query = form.getFirstValue("query");
// validate the form - primitive example of course
if (query == null || query.trim().length() == 0)
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, "Query is required.");
// do something
SearchResults searchResults = SearchEngine.doSearch(query);
// return a HTML representation
return new StringRepresentation(searchResults.asHtmlString(), MediaType.TEXT_HTML);
}
The advantages of using this approach include the incoming representation being automatically converted to a useful form, the method can be named whatever makes sense for your application, and just by scanning the class you can see which class methods handle which HTTP methods, for what kind of representations.