What do double curly brackets mean in struct declaration? - go

Can someone please explain me what do double curly brackets {{ mean in this code ? :
func (t *testService) APIs() []rpc.API {
return []rpc.API{{
Namespace: "test",
Version: "1.0",
Service: &TestAPI{
state: &t.state,
peerCount: &t.peerCount,
},
}}
}
AFIK single curly bracket is enough to create a struct, so why to double it?
the API struct is defined like this:
package rpc
// API describes the set of methods offered over the RPC interface
type API struct {
Namespace string // namespace under which the rpc methods of Service are exposed
Version string // api version for DApp's
Service interface{} // receiver instance which holds the methods
Public bool // indication if the methods must be considered safe for public use
}

It's a slightly shorter version of this (fewer lines and less indenting):
return []rpc.API{
{
Namespace: "test",
Version: "1.0",
Service: &TestAPI{
state: &t.state,
peerCount: &t.peerCount,
},
},
}
It's a slice of structs with one element in it.

[]rpc.API{ } defines an empty slice of rpc.API's. You can put any number of rpc.API's inside those curly brackets to make them elements of the slice.
The code you have is the same as:
a := rpc.API{ Namespace: "test", ... }
return []rpc.API{ a }

Related

Golang invopop jsonschema usage of if/then/else

I'm using the library invopop/jsonschema for generating our json-schema based on go struct tags. But I struggle on how to use the if/then/else attributes.
I was doing something like this
type Boulou struct {
Name string `json:"name" jsonschema:"required,minLength=1,description=unique name"`
Transformers []TransformerConfig `json:"transformers" jsonschema:"title=transformers,if=properties.kind.const=convert_swim,then=required[0]=convert_swim_config"`
}
But does not seems to work (i made a go playground if you would like to play with).
Thanks in advance !
Resources:
json-schema spec for conditions: https://json-schema.org/understanding-json-schema/reference/conditionals.html
These complex use-cases aren't supported all that well using Go tags in invopop/jsonschema. Anything that breaks out of regular use-cases I'd recommend implementing the JSONSchema() method so you can define the object manually. Following your example:
type Boulou struct {
Name string `json:"name"`
Transformers []TransformerConfig `json:"transformers"`
}
func (Boulou) JSONSchema() *jsonschema.Schema {
props = orderedmap.New()
props.Set("name", &jsonschema.Schema{
Type: "string",
Title: "Name",
})
props.Set("transformers", &jsonschema.Schema{
Type: "array",
Title: "Transformers",
Items: &jsonschema.Schema{
Ref: ".....",
If: "properties.kind.const=convert_swim",
Then: "required[0]=convert_swim_config",
},
})
return &jsonschema.Schema{
Type: "object",
Title: "Boulou",
Properties: props,
}
}
I haven't tested this directly, but I'm sure you get the idea. You'll need to figure out what the Ref for your TransformerConfig is manually.
Update: there is now a new PR #52 which once launched, should make this much easier to do!

Apollo Client 3: How to implement caching on client side for graphql interfaces?

I have a case where I have an interface, which has different type implementations defined in graphql. I may not be able to share the exact code. But the case looks something like:
interface Character {
name: String!
}
type Human implements Character {
name: String!
friends: [Character]
}
type Droid implements Character {
name: String!
material: String
}
There is query which returns either Human or Droid type in response.
Response may contain something like:
{
name: 'Human_01',
friends: []
__typename: 'Human'
}
or
{
name: 'Droid_01',
material: 'Aluminium'
__typename: 'Droid'
}
I am using Apollo Client 3 on client side for querying the data and have fragments for these like:
fragment Human on Human {
friends
}
fragment Droid on Droid {
material
}
fragment Character on Character {
name
...Human
...Droid
}
I am querying for the Character data as:
character {
...Character
}
Since, this is the case of interface, and as defined in the docs for Apollo client 3, we need to use possibleTypes in order to match the fragments in such cases. For caching purpose, I have defined InMemoryCache as:
new InMemoryCache({ possibleTypes: { Character: ['Human', 'Droid'] } })
The primary key field for a Character implementation is the name field, which I need to use in order to store its value in cache.
In Apollo client 3, it is mentioned to use typePolicies for defining keyFields for a type.
So, I need to ask as to whether I should define, type policy for both type implementations, specifying keyFields as name in both cases like:
new InMemoryCache({
possibleTypes: { Character: ['Human', 'Droid'] },
typePolicies: { Human: { keyFields: ['name'] }, Droid: { keyFields: ['name'] } }
});
In my example, I have provided only 2 such type implementations but there can be n number of type implementations corresponding to Character interface. So, in that case I will need to define keyFields as name in typePolicies for all the n type implementations.
So, does there exist any better way of implementing caching wrt these types of interface implementations ?
Any help would really be appreciated. Thanks!!!
Inheritance of type and field policies is coming in the next minor version of #apollo/client, v3.3!
You can try it out now by installing #apollo/client#3.3.0-beta.5.
To stay up to date on the progress of the v3.3 release, see this pull request.

Is there a better way to declare json variable

Declaring a variable of type map[string]map[string]... is not ideal, is there a better way
snaps := map[string]map[string]map[string]map[string]string{
"distros": {
"aws": {
"eu-west-1": {
"snap-0": "/dev/sdm",
},
"eu-west-2": {
"snap-1": "/dev/sdm",
},
},
},
}
fmt.Println(snaps["distros"]["aws"]["eu-west-1"])
The simplest way would be to use the type map[string]interface{}. Since the empty interface, interface{}, refers to any type and therefore handles the arbitrarily nested nature of JSON.
To do this you'll have to write your literal data as a string first and then parse the string into a Go map.
With that in mind here is a refactor of your example:
first: import "encoding/json", then
snapsStr := `{
"distros": {
"aws": {
"eu-west-1" : {
"snap-0": "/dev/sdm"
},
"eu-west-2": {
"snap-1": "/dev/sdm"
}
}
}
}`
var snaps map[string]interface{}
json.Unmarshal([]byte(snapsStr), &snaps)
And now snaps is as desired.
This is the most generic format for JSON data in Go and is one of the ways that the Go JSON library handles types for JSON. See these docs: https://golang.org/pkg/encoding/json/#Unmarshal

Flutter internationalization - Dynamic strings

I'm translating my app to spanish using the intl package.
locales.dart
class AppLocale {
...
String get folder => Intl.message("Folder", name: 'folder');
...
}
messages_es.dart
class MessageLookup extends MessageLookupByLibrary {
get localeName => 'es';
final messages = _notInlinedMessages(_notInlinedMessages);
static _notInlinedMessages(_) => <String, Function> {
"folder": MessageLookupByLibrary.simpleMessage("Carpeta"),
};
}
I call it using the following code:
AppLocale.of(context).folder
It is working fine.
However, I need to create "dynamic" strings. For example:
"Hi, {$name}"
Then I would call this string, passing this "name" as parameter, or something like this. It would be translate as "Hola, {$name}" in spanish.
It is possible using this intl package?
If you follow the official internationalization docs and specify all your phrases in .arb files, you can do parameters like this:
{
"greeting": "Hi, {name}!",
"#greeting": {
"description": "Greet the user by their name.",
"placeholders": {
"name": {
"type": "String",
"example": "Jane"
}
}
}
}
When you compile your code, a function like the following will be generated for you, complete with a nice docbloc to power your IDE tooltips:
/// Greet the user by their name.
///
/// In en, this message translates to:
/// **'Hi, {name}!'**
String greeting(String name);
So you can just use it like this:
Text(AppLocalizations.of(context)!.greeting("Koos"))
The README of the intl package explains that example
https://github.com/dart-lang/intl
The purpose of wrapping the message in a function is to allow it to
have parameters which can be used in the result. The message string is
allowed to use a restricted form of Dart string interpolation, where
only the function's parameters can be used, and only in simple
expressions. Local variables cannot be used, and neither can
expressions with curly braces. Only the message string can have
interpolation. The name, desc, args, and examples must be literals and
not contain interpolations. Only the args parameter can refer to
variables, and it should list exactly the function parameters. If you
are passing numbers or dates and you want them formatted, you must do
the formatting outside the function and pass the formatted string into
the message.
greetingMessage(name) => Intl.message(
"Hello $name!",
name: "greetingMessage",
args: [name],
desc: "Greet the user as they first open the application",
examples: const {'name': "Emily"});
print(greetingMessage('Dan'));
Below this section there are more complex examples explained that also deal with plurals and genders.
In order to use placeholders in your translations you need to:
Add that placeholder as a getter argument
Mention that placeholder with $ prefix in the translation (ie $name)
Add the placeholder in args list when calling Intl.message
So a full example looks like this:
greetingMessage(name) => Intl.message(
"Hello $name!",
name: 'greetingMessage',
args: [name]
);
Follow this link. Once you have finished all steps, do the below changes in your .arb file:
{
"title": "App Title",
"helloWorld": "{name1} and {name2} must be different",
"#helloWorld": {
"description": "The conventional newborn programmer greeting",
"placeholders": {
"name1": {
"type": "String"
},
"name2": {
"type": "String"
}
}
},
"appInfo": "Information about your app",
}

What flag to fmt.Printf to follow pointers recursively?

I'm having trouble printing a struct when failing test cases. It's a pointer to a slice of pointers to structs, or *[]*X. The problem is that I need to know the contents of the X-structs inside the slice, but I cannot get it to print the whole chain. It only prints their addresses, since it's a pointer. I need it to follow the pointers.
This is however useless since the function I want to test modifies their contents, and modifying the test code to not use pointers just means I'm not testing the code with pointers (so that wouldn't work).
Also, just looping through the slice won't work, since the real function uses reflect and might handle more than one layer of pointers.
Simplified example:
package main
import "fmt"
func main() {
type X struct {
desc string
}
type test struct {
in *[]*X
want *[]*X
}
test1 := test{
in: &[]*X{
&X{desc: "first"},
&X{desc: "second"},
&X{desc: "third"},
},
}
fmt.Printf("%#v", test1)
}
example output:
main.test{in:(*[]*main.X)(0x10436180), want:(*[]*main.X)(nil)}
(code is at http://play.golang.org/p/q8Its5l_lL )
I don't think fmt.Printf has the functionality you are looking for.
You can use the https://github.com/davecgh/go-spew library.
spew.Dump(test1)
You can use the valast (valast.String()) library alternatively.
For the example the out is:
test{in: &[]*X{
{desc: "first"},
{desc: "second"},
{desc: "third"},
}}
For spew (spew.Sdump()) it looks like:
(main.test) {
in: (*[]*main.X)(0xc000098090)((len=3 cap=3) {
(*main.X)(0xc000088300)({
desc: (string) (len=5) "first"
}),
(*main.X)(0xc000088310)({
desc: (string) (len=6) "second"
}),
(*main.X)(0xc000088320)({
desc: (string) (len=5) "third"
})
}),
want: (*[]*main.X)(<nil>)
}

Resources