Deserializing an F# discriminated union with protobuf-net - serialization

Using the following SO answer as a guideline: Serializing F# discriminated unions with protobuf
I have put together a way to serialize a simple F# discriminated union. Unfortunately I cannot get it to serialize the second case of the DU without throwing a stackoverflow exception. What am I doing wrong?
CODE
open System
open System.IO
open System.Collections.Generic
open ProtoBuf
[<ProtoContract>]
[<ProtoInclude(100, "Program+DU+Good")>]
[<ProtoInclude(200, "Program+DU+Bad")>]
type DU =
| Good of bool
| Bad of int
with
override this.ToString() =
match this with
| Good i -> i.ToString()
| Bad s -> s.ToString()
[<ProtoContract; Serializable>]
type Person(name:string, age:int, du:DU) =
let mutable name = name
let mutable age = age
let mutable du = du
new() = Person("",0,Good true)
[<ProtoMember(1)>]
member this.Name
with get() = name
and set(v) = name <- v
[<ProtoMember(2)>]
member this.Age
with get() = age
and set(v) = age <- v
[<ProtoMember(3)>]
member this.DU
with get() = du
and set(v) = du <- v
override this.ToString() = this.Name + ", " + this.Age.ToString() + ", " + this.DU.ToString()
[<EntryPoint>]
let main argv =
// typeof vs typedefof ?
ProtoBuf.Meta.RuntimeTypeModel.Default.[typeof<DU>.GetNestedType("Good")].Add("item").UseConstructor <- false
ProtoBuf.Meta.RuntimeTypeModel.Default.[typeof<DU>.GetNestedType("Bad")].Add("item").UseConstructor <- false
//RuntimeTypeModel.Default.[typeof<DU>].CompileInPlace() // doesn't seem to make any difference
let p1 = Person("Sam", 38, Good false)
let p2 = Person("Cand", 34, Bad 99)
let filePath = #"C:\Temp\protocol.bin"
if not (File.Exists filePath) then
let fs = File.Create(filePath)
fs.Close()
use fileStream1 = new System.IO.FileStream(filePath, FileMode.Truncate, FileAccess.Write)
ProtoBuf.Serializer.Serialize<Person>(fileStream1, p2) // p1 does work because it uses the first case of the DU
fileStream1.Close()
use fileStream2 = new System.IO.FileStream(filePath, FileMode.Open, FileAccess.Read)
let result = ProtoBuf.Serializer.Deserialize<Person>(fileStream2) // stackoverflow exception ONLY for p2
fileStream2.Close()
printfn "%A" result
Console.ReadLine() |> ignore
0 // return an integer exit code

Related

Syntax Highlighting for go in vb.net

Ok so I have been making a simple code editor in vb.net for go.. (for personal uses)
I tried this code -
Dim tokens As String = "(break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var)"
Dim rex As New Regex(tokens)
Dim mc As MatchCollection = rex.Matches(TextBox2.Text)
Dim StartCursorPosition As Integer = TextBox2.SelectionStart
For Each m As Match In mc
Dim startIndex As Integer = m.Index
Dim StopIndex As Integer = m.Length
TextBox2.[Select](startIndex, StopIndex)
TextBox2.SelectionColor = Color.FromArgb(0, 122, 204)
TextBox2.SelectionStart = StartCursorPosition
TextBox2.SelectionColor = Color.RebeccaPurple
Next
but I couldn't add something like print statements say I want a fmt.Println("Hello World"), that is not possible, anyone help me?
I want a simple result that will do proper syntax without glitching text colors like this current code does.
Here's a code showing how to update highlighting with strings and numbers.
You would need to tweak it further to support syntax like comments, etc.
private Regex BuildExpression()
{
string[] exprs = {
"(break|default|func|interface|select|case|defer|go|map|struct|chan|else|goto|package|switch|const|fallthrough|if|range|type|continue|for|import|return|var)",
#"([0-9]+\.[0-9]*(e|E)(\+|\-)?[0-9]+)|([0-9]+\.[0-9]*)|([0-9]+)",
"(\"\")|\"((((\\\\\")|(\"\")|[^\"])*\")|(((\\\\\")|(\"\")|[^\"])*))"
};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < exprs.Length; i++)
{
string expr = exprs[i];
if ((expr != null) && (expr != string.Empty))
sb.Append(string.Format("(?<{0}>{1})", "_" + i.ToString(), expr) + "|");
}
if (sb.Length > 0)
sb.Remove(sb.Length - 1, 1);
RegexOptions options = RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase;
return new Regex(sb.ToString(), options);
}
private void HighlightSyntax()
{
var colors = new Dictionary<int, Color>();
var expression = BuildExpression();
Color[] clrs = { Color.Teal, Color.Red, Color.Blue };
int[] intarray = expression.GetGroupNumbers();
foreach (int i in intarray)
{
var name = expression.GroupNameFromNumber(i);
if ((name != null) && (name.Length > 0) && (name[0] == '_'))
{
var idx = int.Parse(name.Substring(1));
if (idx < clrs.Length)
colors.Add(i, clrs[idx]);
}
}
foreach (Match match in expression.Matches(richTextBox1.Text))
{
int index = match.Index;
int length = match.Length;
richTextBox1.Select(index, length);
for (int i = 0; i < match.Groups.Count; i++)
{
if (match.Groups[i].Success)
{
if (colors.ContainsKey(i))
{
richTextBox1.SelectionColor = colors[i];
break;
}
}
}
}
}
What we found during development of our Code Editor libraries, is that the regular expression-based parsers are hard to adapt to fully support advanced syntax like contextual keywords (LINQ) or interpolated strings.
You might find a bit more information here:
https://www.alternetsoft.com/blog/code-parsing-explained
The most accurate syntax highlighting for VB.NET can be implemented using Microsoft.CodeAnalysis API, it's the same API used internally by Visual Studio text editor.
Below is sample code showing how to get classified spans for VB.NET code (every span contains start/end position within the text and classification type, i.e. keyword, string, etc.). These spans then can be used to highlight text inside a textbox.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Classification;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;
public class VBClassifier
{
private Workspace workspace;
private static string FileContent = #"
Public Sub Run()
Dim test as TestClass = new TestClass()
End Sub";
public void Classify()
{
var project = InitProject();
var doc = AddDocument(project, "file1.vb", FileContent);
var spans = Classify(doc);
}
protected IEnumerable<ClassifiedSpan> Classify(Document document)
{
var text = document.GetTextAsync().Result;
var span = new TextSpan(0, text.Length);
return Classifier.GetClassifiedSpansAsync(document, span).Result;
}
protected Document AddDocument(Project project, string fileName, string code)
{
var documentId = DocumentId.CreateNewId(project.Id, fileName);
ApplySolutionChanges(s => s.AddDocument(documentId, fileName, code, filePath: fileName));
return workspace.CurrentSolution.GetDocument(documentId);
}
protected virtual void ApplySolutionChanges(Func<Solution, Solution> action)
{
var solution = workspace.CurrentSolution;
solution = action(solution);
workspace.TryApplyChanges(solution);
}
protected MefHostServices GetRoslynCompositionHost()
{
IEnumerable<Assembly> assemblies = MefHostServices.DefaultAssemblies;
var compositionHost = MefHostServices.Create(assemblies);
return compositionHost;
}
protected Project CreateDefaultProject()
{
var solution = workspace.CurrentSolution;
var projectId = ProjectId.CreateNewId();
var projectName = "VBTest";
ProjectInfo projectInfo = ProjectInfo.Create(
projectId,
VersionStamp.Default,
projectName,
projectName,
LanguageNames.VisualBasic,
filePath: null);
ApplySolutionChanges(s => s.AddProject(projectInfo));
return workspace.CurrentSolution.Projects.FirstOrDefault();
}
protected Project InitProject()
{
var host = GetRoslynCompositionHost();
workspace = new AdhocWorkspace(host);
return CreateDefaultProject();
}
}
Update:
Here's a Visual Studio project demonstrating both approaches:
https://drive.google.com/file/d/1LLuzy7yDFAE-v40I7EswECYQSthxheEf/view?usp=sharing

Use method in sql interpolator

Using scala 2.11 and Slick 2.11
In a scala class, I have 2 methods:
getSQL which returns String SQL
getSqlStreamingAction which returns a composed SqlStreamingAction using sql interpolator
The code
def getSQL(id: Int): String = {
var fields_string = "";
for ((k,v) <- field_map) fields_string += k + ", ";
fields_string = fields_string.dropRight(2) // remove last ", "
"SELECT "+ fields_string +" FROM my_table WHERE id = " + id
}
def getSqlStreamingAction (id: Int): SqlStreamingAction[Vector[OtherObject], OtherObject, Effect] = {
val r = GetResult(r => OtherObject(r.<<, r.<<))
// this works
var fields_string = "";
for ((k,v) <- field_map) fields_string += k + ", ";
sql"""SELECT #$fields_string FROM my_table WHERE id = #$id""".as(r)
// But I want to use the method getSQL to retrieve the SQL String
// I imagine something like this, but of course it doesn't work :)
//sql"getSQL($id)".as(r)
I want to have separated methods for unit tests purposes, so I want to use getSQL method for sql interpolator
So, how can I use a method for Slick sql interpolator?
Note: I'm pretty new in Scala
-1 for me.
Solution:
def getSqlStreamingAction (id: Int): SqlStreamingAction[Vector[OtherObject], OtherObject, Effect] = {
val r = GetResult(r => OtherObject(r.<<, r.<<))
var sql_string: String = getSQL(id)
sql"""#$sql_string""".as(r)

Groovy - Define variable where the variable name is passed by another variable

I want define a variable in groovy with where the variable name is passed by another variable.
Something like.
def runExtFunc(varName){
def varName // => def abc
varName = load 'someFile.groovy' // abc = load 'someFile.groovy'
varName."$varName"() // -> abc.abc() (run function defined in File)
}
[...]
runExtFunc('abc') // -> abc.abc() (Function abc defined in File)
[...]
runExtFunc('xyz') // -> xyz.xyz() (Function xyz defined in File)
[...]
Sadly def varName defines the variable varName and not abc. When I call runExtFunc twice an error occoures bacause varName is already defined.
I also tried
def runExtFunc(varName){
def "${varName}" // => def abc
[...]
"${varName}" = load 'someFile.groovy'
[...]
}
which doesn't work either.
Any suggestions?
This is the wrong approach. Normally you would use List, Map or Set data structures, which allow you to save a collection and access specific elements in the collection.
List allows you to hold specific values (unique or non-unique). Set allows you to hold specific values (all unique). Map allows you to have Key, Value pairs (Key must be unique) .
Read more here
groovy list,
groovy map
Try this (if I understand you correctly):
def dummyFunc(varName) {
new GroovyShell(this.binding).evaluate("${varName}")
}
dummyFunc('abc')
abc = "Hello there"
println abc
Prints
Hello there
See here
https://godless-internets.org/2020/02/14/extracting-jenkins-credentials-for-use-in-another-place/
secret_var="SECRET_VALUE_${secret_index}"
aws ssm put-parameter --name ${param_arn} --type "SecureString" --value ${!secret_var} --region us-east-2 --overwrite
I'm entering here a code sample we've done.
Please, feel free to comment.
http://groovy-lang.org/syntax.html
https://godless-internets.org/2020/02/14/extracting-jenkins-credentials-for-use-in-another-place/
def int fileContentReplaceDynamic(String filePathVar, String envTail = "",
String [] keysToIgnore = new String[0]){
def filePath = readFile filePathVar
def lines = filePath.readLines()
//def regex = ~/\b__\w*\b/
String regex = "__(.*?)__"
ArrayList credentialsList = new ArrayList();
ArrayList<String> keysToIgnoreList = new ArrayList<String>(Arrays.asList(keysToIgnore));
for (line in lines){
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE)
Matcher matcher = pattern.matcher(line)
while (matcher.find()){
String credKeyName = matcher.group().replaceAll("__","")
if ((! credentialsList.contains(credKeyName)) &&
(! keysToIgnoreList.contains(credKeyName))) {
credentialsList.add(credKeyName)
} else {
log.info("Credencial ignorada o ya incluida: ${credKeyName}")
}
}
}
if(credentialsList.size() <= 0){
log.info("No hay variables para aplicar transformada")
return 0
}
log.info("Numero de credenciales encontradas a sustituir: " + credentialsList.size())
String credentialsListString = String.join(", ", credentialsList);
log.info("Credenciales: " + credentialsListString)
def credsRequest = null
for(def credKeyName in credentialsList){
// Retrieve the values of the variables by environment tail name.
String credKeyNameByEnv = "${credKeyName}";
if ((envTail != null) && (! envTail.trim().isEmpty())) {
credKeyNameByEnv = credKeyNameByEnv + "-" + envTail.trim().toUpperCase();
}
// Now define the name of the variable we'll use
// List<org.jenkinsci.plugins.credentialsbinding.MultiBinding>
// Tip: java.lang.ClassCastException:
// org.jenkinsci.plugins.credentialsbinding.impl.BindingStep.bindings
// expects class org.jenkinsci.plugins.credentialsbinding.MultiBinding
String varName = "var_${credKeyNameByEnv}"
if (credsRequest == null) {
// Initialize
credsRequest = [string(credentialsId: "${credKeyNameByEnv}", variable: "${varName}")]
} else {
// Add element
credsRequest << string(credentialsId: "${credKeyNameByEnv}", variable: "${varName}")
}
}
int credsProcessed = 0
def passwordsRequest = null
StringBuilder sedReplacements = new StringBuilder();
// Now ask jenkins to fill in all variables with values
withCredentials(credsRequest) {
for(def credKeyName in credentialsList){
String credKeyVar = "var_${credKeyName}"
log.info("Replacing value for credential ${credKeyName} stored in ${credKeyVar}")
String credKeyValueIn = "${!credKeyVar}"
String credKeyValue = null;
if ("empty_string_value".equals(credKeyValueIn.trim())) {
credKeyValue = "";
} else {
credKeyValue = credKeyValueIn.replaceAll(/(!|"|#|#|\$|%|&|\/|\(|\)|=|\?)/, /\\$0/)
}
if (passwordsRequest == null) {
// Initialize
passwordsRequest = [[password: "${credKeyValue}" ]]
} else {
// Add element
passwordsRequest << [password: "${credKeyValue}" ]
}
sedReplacements.append("s/__${credKeyName}__/${credKeyValue}/; ")
credsProcessed++
}
}
wrap([$class: "MaskPasswordsBuildWrapper", varPasswordPairs: passwordsRequest ]){
String sedReplacementsString = sedReplacements.toString().trim();
if (sedReplacementsString.endsWith(";")) {
sedReplacementsString = sedReplacementsString.substring(0, sedReplacementsString.length() -1);
sedReplacementsString = sedReplacementsString + "g;"
}
sh """sed -i "${sedReplacementsString}" ${filePathVar}"""
}
log.info("Finaliza la transformada. Transformados: ${credsProcessed}/${credentialsList.size()} ")
if (credsProcessed != credentialsList.size()) {
log.info("Hay credenciales que no se han podido encontrar en el vault de Jenkins.")
log.info("Si estas guardando cadenas vacias en credenciales, guarda en su lugar el valor 'empty_string_value'.");
return -1
}
return 0;
}

Using OWL API, given an OWLClass, how can I get <rdfs:label> of it?

Using OWL API 3.4.9.
Given an OWLClass and on ontology, how can I get <rdfs:label> of that OWLClass in that ontology?
I hope to get the label in the type of String.
Inspired from the guide to the OWL-API, the following code should work (not tested):
//Initialise
OWLOntologyManager m = create();
OWLOntology o = m.loadOntologyFromOntologyDocument(pizza_iri);
OWLDataFactory df = OWLManager.getOWLDataFactory();
//Get your class of interest
OWLClass cls = df.getOWLClass(IRI.create(pizza_iri + "#foo"));
// Get the annotations on the class that use the label property (rdfs:label)
for (OWLAnnotation annotation : cls.getAnnotations(o, df.getRDFSLabel())) {
if (annotation.getValue() instanceof OWLLiteral) {
OWLLiteral val = (OWLLiteral) annotation.getValue();
// look for portuguese labels - can be skipped
if (val.hasLang("pt")) {
//Get your String here
System.out.println(cls + " labelled " + val.getLiteral());
}
}
}
The accepted answer is valid for OWLAPI version 3.x (3.4 and 3.5 versions) but not for OWL-API 4.x and newer.
To retrieve rdfs:label values asserted against OWL classes, try this instead:
OWLClass c = ...;
OWLOntology o = ...;
IRI cIRI = c.getIRI();
for(OWLAnnotationAssertionAxiom a : ont.getAnnotationAssertionAxioms(cIRI)) {
if(a.getProperty().isLabel()) {
if(a.getValue() instanceof OWLLiteral) {
OWLLiteral val = (OWLLiteral) a.getValue();
System.out.println(c + " labelled " + val.getLiteral());
}
}
}
EDIT
As Ignazio has pointed out, EntitySearcher can also be used, for example:
OWLClass c = ...;
OWLOntology o = ...;
for(OWLAnnotation a : EntitySearcher.getAnnotations(c, o, factory.getRDFSLabel())) {
OWLAnnotationValue val = a.getValue();
if(val instanceof OWLLiteral) {
System.out.println(c + " labelled " + ((OWLLiteral) val).getLiteral());
}
}
Here is a method I wrote to extract labels from a class.
private List<String> classLabels(OWLClass class){
List<String> labels;
labels = ontologiaOWL.annotationAssertionAxioms(class.getIRI())
//get only the annotations with rdf Label property
.filter(axiom -> axiom.getProperty().getIRI().getIRIString().equals(OWLRDFVocabulary.RDFS_LABEL.getIRI().getIRIString()))
.map(axiom -> axiom.getAnnotation())
.filter(annotation-> annotation.getValue() instanceof OWLLiteral)
.map(annotation -> (OWLLiteral) annotation.getValue())
.map(literal -> literal.getLiteral())
.collect(Collectors.toList());
return labels;
}

initialization of fsharp class field

I have a class bound to a XAML file.
Upon the first call to it, the field selectedudl is = null.
Do you know why it is the case ?
I would have expected it to be = "" ..
type QuotesViewModel() =
inherit ViewModelBase()
let mutable histo = Array.empty
let mutable selectedudl = ""
member x.GetUnderlyings = seq { yield "one"; yield "two"}
member x.SelectedUdl
with get() = selectedudl
and set value =
selectedudl <- value
x.OnPropertyChanged <# x.SelectedUdl #>
x.OnPropertyChanged <# x.SelectedGraph #>
member x.SelectedGraph
with get() =
let graph = asyncquotes.visualizehistoForUdl selectedudl
let host = new System.Windows.Forms.Integration.WindowsFormsHost()
host.Child <- new ChartControl(graph, Dock = DockStyle.Fill)
host