Hollie  Ratke

Hollie Ratke

1618912592

How and Why to Write Enums in Go

An enum , which is short for enumerator , is a set of named constant values. Enums are a powerful tool that allow developers to create complex sets of constants that have useful names yet simple and unique values.

#golang #go #web-development #developer

What is GEEK

Buddha Community

How and Why to Write Enums in Go
Fannie  Zemlak

Fannie Zemlak

1599854400

What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features

Generis: Versatile Go Code Generator

Generis

Versatile Go code generator.

Description

Generis is a lightweight code preprocessor adding the following features to the Go language :

  • Generics.
  • Free-form macros.
  • Conditional compilation.
  • HTML templating.
  • Allman style conversion.

Sample

package main;

// -- IMPORTS

import (
    "html"
    "io"
    "log"
    "net/http"
    "net/url"
    "strconv"
    );

// -- DEFINITIONS

#define DebugMode
#as true

// ~~

#define HttpPort
#as 8080

// ~~

#define WriteLine( {{text}} )
#as log.Println( {{text}} )

// ~~

#define local {{variable}} : {{type}};
#as var {{variable}} {{type}};

// ~~

#define DeclareStack( {{type}}, {{name}} )
#as
    // -- TYPES

    type {{name}}Stack struct
    {
        ElementArray []{{type}};
    }

    // -- INQUIRIES

    func ( stack * {{name}}Stack ) IsEmpty(
        ) bool
    {
        return len( stack.ElementArray ) == 0;
    }

    // -- OPERATIONS

    func ( stack * {{name}}Stack ) Push(
        element {{type}}
        )
    {
        stack.ElementArray = append( stack.ElementArray, element );
    }

    // ~~

    func ( stack * {{name}}Stack ) Pop(
        ) {{type}}
    {
        local
            element : {{type}};

        element = stack.ElementArray[ len( stack.ElementArray ) - 1 ];

        stack.ElementArray = stack.ElementArray[ : len( stack.ElementArray ) - 1 ];

        return element;
    }
#end

// ~~

#define DeclareStack( {{type}} )
#as DeclareStack( {{type}}, {{type:PascalCase}} )

// -- TYPES

DeclareStack( string )
DeclareStack( int32 )

// -- FUNCTIONS

func HandleRootPage(
    response_writer http.ResponseWriter,
    request * http.Request
    )
{
    local
        boolean : bool;
    local
        natural : uint;
    local
        integer : int;
    local
        real : float64;
    local
        escaped_html_text,
        escaped_url_text,
        text : string;
    local
        integer_stack : Int32Stack;

    boolean = true;
    natural = 10;
    integer = 20;
    real = 30.0;
    text = "text";
    escaped_url_text = "&escaped text?";
    escaped_html_text = "<escaped text/>";

    integer_stack.Push( 10 );
    integer_stack.Push( 20 );
    integer_stack.Push( 30 );

    #write response_writer
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="utf-8">
                <title><%= request.URL.Path %></title>
            </head>
            <body>
                <% if ( boolean ) { %>
                    <%= "URL : " + request.URL.Path %>
                    <br/>
                    <%@ natural %>
                    <%# integer %>
                    <%& real %>
                    <br/>
                    <%~ text %>
                    <%^ escaped_url_text %>
                    <%= escaped_html_text %>
                    <%= "<%% ignored %%>" %>
                    <%% ignored %%>
                <% } %>
                <br/>
                Stack :
                <br/>
                <% for !integer_stack.IsEmpty() { %>
                    <%# integer_stack.Pop() %>
                <% } %>
            </body>
        </html>
    #end
}

// ~~

func main()
{
    http.HandleFunc( "/", HandleRootPage );

    #if DebugMode
        WriteLine( "Listening on http://localhost:HttpPort" );
    #end

    log.Fatal(
        http.ListenAndServe( ":HttpPort", nil )
        );
}

Syntax

#define directive

Constants and generic code can be defined with the following syntax :

#define old code
#as new code

#define old code
#as
    new
    code
#end

#define
    old
    code
#as new code

#define
    old
    code
#as
    new
    code
#end

#define parameter

The #define directive can contain one or several parameters :

{{variable name}} : hierarchical code (with properly matching brackets and parentheses)
{{variable name#}} : statement code (hierarchical code without semicolon)
{{variable name$}} : plain code
{{variable name:boolean expression}} : conditional hierarchical code
{{variable name#:boolean expression}} : conditional statement code
{{variable name$:boolean expression}} : conditional plain code

They can have a boolean expression to require they match specific conditions :

HasText text
HasPrefix prefix
HasSuffix suffix
HasIdentifier text
false
true
!expression
expression && expression
expression || expression
( expression )

The #define directive must not start or end with a parameter.

#as parameter

The #as directive can use the value of the #define parameters :

{{variable name}}
{{variable name:filter function}}
{{variable name:filter function:filter function:...}}

Their value can be changed through one or several filter functions :

LowerCase
UpperCase
MinorCase
MajorCase
SnakeCase
PascalCase
CamelCase
RemoveComments
RemoveBlanks
PackStrings
PackIdentifiers
ReplacePrefix old_prefix new_prefix
ReplaceSuffix old_suffix new_suffix
ReplaceText old_text new_text
ReplaceIdentifier old_identifier new_identifier
AddPrefix prefix
AddSuffix suffix
RemovePrefix prefix
RemoveSuffix suffix
RemoveText text
RemoveIdentifier identifier

#if directive

Conditional code can be defined with the following syntax :

#if boolean expression
    #if boolean expression
        ...
    #else
        ...
    #end
#else
    #if boolean expression
        ...
    #else
        ...
    #end
#end

The boolean expression can use the following operators :

false
true
!expression
expression && expression
expression || expression
( expression )

#write directive

Templated HTML code can be sent to a stream writer using the following syntax :

#write writer expression
    <% code %>
    <%@ natural expression %>
    <%# integer expression %>
    <%& real expression %>
    <%~ text expression %>
    <%= escaped text expression %>
    <%! removed content %>
    <%% ignored tags %%>
#end

Limitations

  • There is no operator precedence in boolean expressions.
  • The --join option requires to end the statements with a semicolon.
  • The #writer directive is only available for the Go language.

Installation

Install the DMD 2 compiler (using the MinGW setup option on Windows).

Build the executable with the following command line :

dmd -m64 generis.d

Command line

generis [options]

Options

--prefix # : set the command prefix
--parse INPUT_FOLDER/ : parse the definitions of the Generis files in the input folder
--process INPUT_FOLDER/ OUTPUT_FOLDER/ : reads the Generis files in the input folder and writes the processed files in the output folder
--trim : trim the HTML templates
--join : join the split statements
--create : create the output folders if needed
--watch : watch the Generis files for modifications
--pause 500 : time to wait before checking the Generis files again
--tabulation 4 : set the tabulation space count
--extension .go : generate files with this extension

Examples

generis --process GS/ GO/

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder.

generis --process GS/ GO/ --create

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, creating the output folders if needed.

generis --process GS/ GO/ --create --watch

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, creating the output folders if needed and watching the Generis files for modifications.

generis --process GS/ GO/ --trim --join --create --watch

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, trimming the HTML templates, joining the split statements, creating the output folders if needed and watching the Generis files for modifications.

Version

2.0

Author: Senselogic
Source Code: https://github.com/senselogic/GENERIS 
License: View license

#go #golang #code 

Go-enum: An Enum Generator for Go

go-enum 

An enum generator for go

How it works

go-enum will take a commented type declaration like this:

// ENUM(jpeg, jpg, png, tiff, gif)
type ImageType int

and generate a file with the iota definition along various optional niceties that you may need:

const (
    // ImageTypeJpeg is a ImageType of type Jpeg.
    ImageTypeJpeg ImageType = iota
    // ImageTypeJpg is a ImageType of type Jpg.
    ImageTypeJpg
    // ImageTypePng is a ImageType of type Png.
    ImageTypePng
    // ImageTypeTiff is a ImageType of type Tiff.
    ImageTypeTiff
    // ImageTypeGif is a ImageType of type Gif.
    ImageTypeGif
)

// String implements the Stringer interface.
func (x ImageType) String() string

// ParseImageType attempts to convert a string to a ImageType.
func ParseImageType(name string) (ImageType, error)

// MarshalText implements the text marshaller method.
func (x ImageType) MarshalText() ([]byte, error)

// UnmarshalText implements the text unmarshaller method.
func (x *ImageType) UnmarshalText(text []byte) error

Fear not the fact that the MarshalText and UnmarshalText are generated rather than JSON methods... they will still be utilized by the default JSON encoding methods.

If you find that the options given are not adequate for your use case, there is an option to add a custom template (-t flag) to the processing engine so that your custom code can be created!

Goal

The goal of go-enum is to create an easy to use enum generator that will take a decorated type declaration like type EnumName int and create the associated constant values and funcs that will make life a little easier for adding new values. It's not perfect, but I think it's useful.

I took the output of the Stringer command as the String() method, and added a way to parse a string value.

Installation

You can now download a release directly from github and use that for generating your enums! (Thanks to GoReleaser)

I did not specify any overrides on the release binary names, so uname -s and uname -m should provide the correct version of the binary for your distro.

    curl -fsSL "https://github.com/abice/go-enum/releases/download/$(GO_ENUM_VERSION)/go-enum_$(uname -s)_$(uname -m)" -o go-enum

Adding it to your project

Using go generate

  1. Add a go:generate line to your file like so... //go:generate go-enum -f=$GOFILE --marshal
  2. Run go generate like so go generate ./...
  3. Enjoy your newly created Enumeration!

Using Makefile

If you prefer makefile stuff, you can always do something like this:

STANDARD_ENUMS = example/animal_enum.go \
    example/color_enum.go

NULLABLE_ENUMS = example/sql_enum.go

$(STANDARD_ENUMS): GO_ENUM_FLAGS=--nocase --marshal --names --ptr
$(NULLABLE_ENUMS): GO_ENUM_FLAGS=--nocase --marshal --names --sqlnullint --ptr

enums: $(STANDARD_ENUMS) $(NULLABLE_ENUMS)

# The generator statement for go enum files.  Files that invalidate the
# enum file: source file, the binary itself, and this file (in case you want to generate with different flags)
%_enum.go: %.go $(GOENUM) Makefile
    $(GOENUM) -f $*.go $(GO_ENUM_FLAGS)

Command options

go-enum --help

NAME:
   go-enum - An enum generator for go

USAGE:
   go-enum [global options] [arguments...]

VERSION:
   x.y.z

GLOBAL OPTIONS:
   --file value, -f value      The file(s) to generate enums.  Use more than one flag for more files.
   --noprefix                  Prevents the constants generated from having the Enum as a prefix. (default: false)
   --lower                     Adds lowercase variants of the enum strings for lookup. (default: false)
   --nocase                    Adds case insensitive parsing to the enumeration (forces lower flag). (default: false)
   --marshal                   Adds text (and inherently json) marshalling functions. (default: false)
   --sql                       Adds SQL database scan and value functions. (default: false)
   --flag                      Adds golang flag functions. (default: false)
   --prefix value              Replaces the prefix with a user one.
   --names                     Generates a 'Names() []string' function, and adds the possible enum values in the error response during parsing (default: false)
   --nocamel                   Removes the snake_case to CamelCase name changing (default: false)
   --ptr                       Adds a pointer method to get a pointer from const values (default: false)
   --sqlnullint                Adds a Null{{ENUM}} type for marshalling a nullable int value to sql (default: false)
   --sqlnullstr                Adds a Null{{ENUM}} type for marshalling a nullable string value to sql.  If sqlnullint is specified too, it will be Null{{ENUM}}Str (default: false)
   --template value, -t value  Additional template file(s) to generate enums.  Use more than one flag for more files. Templates will be executed in alphabetical order.
   --alias value, -a value     Adds or replaces aliases for a non alphanumeric value that needs to be accounted for. [Format should be "key:value,key2:value2", or specify multiple entries, or both!]
   --help, -h                  show help (default: false)
   --version, -v               print the version (default: false)

Syntax

The parser looks for comments on your type defs and parse the enum declarations from it. The parser will look for ENUM( and continue to look for comma separated values until it finds a ). You can put values on the same line, or on multiple lines.
If you need to have a specific value jump in the enum, you can now specify that by adding =numericValue to the enum declaration. Keep in mind, this resets the data for all following values. So if you specify 50 in the middle of an enum, each value after that will be 51, 52, 53...

Comments

You can use comments inside enum that start with //
The comment must be at the end of the same line as the comment value, only then it will be added as a comment to the generated constant.

// Commented is an enumeration of commented values
/*
ENUM(
value1 // Commented value 1
value2
value3 // Commented value 3
)
*/
type Commented int

The generated comments in code will look something like:

...
const (
    // CommentedValue1 is a Commented of type Value1
    // Commented value 1
    CommentedValue1 Commented = iota
    // CommentedValue2 is a Commented of type Value2
    CommentedValue2
    // CommentedValue3 is a Commented of type Value3
    // Commented value 3
    CommentedValue3
)
...

Example

There are a few examples in the example directory. I've included one here for easy access, but can't guarantee it's up to date.

// Color is an enumeration of colors that are allowed.
/* ENUM(
Black, White, Red
Green = 33 // Green starts with 33
*/
// Blue
// grey=
// yellow
// blue-green
// red-orange
// yellow_green
// red-orange-blue
// )
type Color int32

The generated code will look something like:

// Code generated by go-enum DO NOT EDIT.
// Version: example
// Revision: example
// Build Date: example
// Built By: example

package example

import (
    "fmt"
    "strings"
)

const (
    // ColorBlack is a Color of type Black.
    ColorBlack Color = iota
    // ColorWhite is a Color of type White.
    ColorWhite
    // ColorRed is a Color of type Red.
    ColorRed
    // ColorGreen is a Color of type Green.
    // Green starts with 33
    ColorGreen Color = iota + 30
    // ColorBlue is a Color of type Blue.
    ColorBlue
    // ColorGrey is a Color of type Grey.
    ColorGrey
    // ColorYellow is a Color of type Yellow.
    ColorYellow
    // ColorBlueGreen is a Color of type Blue-Green.
    ColorBlueGreen
    // ColorRedOrange is a Color of type Red-Orange.
    ColorRedOrange
    // ColorYellowGreen is a Color of type Yellow_green.
    ColorYellowGreen
    // ColorRedOrangeBlue is a Color of type Red-Orange-Blue.
    ColorRedOrangeBlue
)

const _ColorName = "BlackWhiteRedGreenBluegreyyellowblue-greenred-orangeyellow_greenred-orange-blue"

var _ColorMap = map[Color]string{
    ColorBlack:         _ColorName[0:5],
    ColorWhite:         _ColorName[5:10],
    ColorRed:           _ColorName[10:13],
    ColorGreen:         _ColorName[13:18],
    ColorBlue:          _ColorName[18:22],
    ColorGrey:          _ColorName[22:26],
    ColorYellow:        _ColorName[26:32],
    ColorBlueGreen:     _ColorName[32:42],
    ColorRedOrange:     _ColorName[42:52],
    ColorYellowGreen:   _ColorName[52:64],
    ColorRedOrangeBlue: _ColorName[64:79],
}

// String implements the Stringer interface.
func (x Color) String() string {
    if str, ok := _ColorMap[x]; ok {
        return str
    }
    return fmt.Sprintf("Color(%d)", x)
}

var _ColorValue = map[string]Color{
    _ColorName[0:5]:                    ColorBlack,
    strings.ToLower(_ColorName[0:5]):   ColorBlack,
    _ColorName[5:10]:                   ColorWhite,
    strings.ToLower(_ColorName[5:10]):  ColorWhite,
    _ColorName[10:13]:                  ColorRed,
    strings.ToLower(_ColorName[10:13]): ColorRed,
    _ColorName[13:18]:                  ColorGreen,
    strings.ToLower(_ColorName[13:18]): ColorGreen,
    _ColorName[18:22]:                  ColorBlue,
    strings.ToLower(_ColorName[18:22]): ColorBlue,
    _ColorName[22:26]:                  ColorGrey,
    strings.ToLower(_ColorName[22:26]): ColorGrey,
    _ColorName[26:32]:                  ColorYellow,
    strings.ToLower(_ColorName[26:32]): ColorYellow,
    _ColorName[32:42]:                  ColorBlueGreen,
    strings.ToLower(_ColorName[32:42]): ColorBlueGreen,
    _ColorName[42:52]:                  ColorRedOrange,
    strings.ToLower(_ColorName[42:52]): ColorRedOrange,
    _ColorName[52:64]:                  ColorYellowGreen,
    strings.ToLower(_ColorName[52:64]): ColorYellowGreen,
    _ColorName[64:79]:                  ColorRedOrangeBlue,
    strings.ToLower(_ColorName[64:79]): ColorRedOrangeBlue,
}

// ParseColor attempts to convert a string to a Color
func ParseColor(name string) (Color, error) {
    if x, ok := _ColorValue[name]; ok {
        return x, nil
    }
    return Color(0), fmt.Errorf("%s is not a valid Color", name)
}

func (x Color) Ptr() *Color {
    return &x
}

// MarshalText implements the text marshaller method
func (x Color) MarshalText() ([]byte, error) {
    return []byte(x.String()), nil
}

// UnmarshalText implements the text unmarshaller method
func (x *Color) UnmarshalText(text []byte) error {
    name := string(text)
    tmp, err := ParseColor(name)
    if err != nil {
        return err
    }
    *x = tmp
    return nil
}

Author: Abice
Source Code: https://github.com/abice/go-enum 
License: MIT License

#go #golang #code #enums 

What You Can Learn about Setting from Classic Sitcoms

Giving your novel a strong sense of place is vital to doing your part to engage the readers without confusing or frustrating them. Setting is a big part of this (though not the whole enchilada — there is also social context and historic period), and I often find writing students and consulting clients erring on one of two extremes.

**Either: **Every scene is set in a different, elaborately-described place from the last. This leads to confusion (and possibly exhaustion and impatience) for the reader, because they have no sense of what they need to actually pay attention to for later and what’s just…there. Are the details of that forest in chapter 2 important? Will I ever be back in this castle again? Is there a reason for this character to be in this particular room versus the one she was in the last time I saw her? Who knows!

Or: There are few or no clues at all as to where the characters are in a scene. What’s in the room? Are they even in a room? Are there other people in th — ope, yes, there are, someone just materialized, what is happening? This all leads to the dreaded “brains in jars” syndrome. That is, characters are only their thoughts and words, with no grounding in the space-time continuum. No one seems to be in a place, in a body, at a time of day.

Everything aspect of writing a novel comes with its difficulties, and there are a lot of moving pieces to manage and deploy in the right balance. When you’re a newer writer, especially, there’s something to be said for keeping things simple until you have a handle on how to manage the arc and scope of a novel-length work. And whether you tend to overdo settings or underdo them, you can learn something from TV, especially classic sitcoms.

Your basic “live studio audience” sitcoms are performed and filmed on sets built inside studios vs. on location. This helps keep production expenses in check and helps the viewer feel at home — there’s a reliable and familiar container to hold the story of any given episode. The writers on the show don’t have to reinvent the wheel with every script.

Often, a show will have no more than two or three basic sets that are used episode to episode, and then a few other easily-understood sets (characters’ workplaces, restaurants, streets scenes) are also used regularly but not every episode.

#creative-writing #writing-exercise #writing-craft #writing #writing-tips #machine learning

Aria Smith

1607333509

Write My Paper for Me Online: Can You Do My Research Paper USA? TheWritingPlanet.com

We understand the paint that understudies need to experience every day considering the course that at whatever point you have completed all your astute necessities for your Ph.D. or of course MA, you’ll need to begin searching after the piece. So what do you think? Okay have the choice to control it with no other individual, or you require dissertation help from a readied capable? As a general rule, it’s a long cycle as you need to make a broad paper out of around 10 to 20 thousand words starting with the presentation of your subject and some time later your explanations behind why it should be dissected. Following the model, you’ll need to make a creation audit that will join the pushing assessments that will other than control your paper’s theoretical structure. It sounds tangled. Really, it is.

This assignment is one of the most tiring and unusual ones an understudy needs to look during his 16 to 18 years of training. In any case, once more, we have your back this time too. I handle the focuses above may have made you anxious about this undertaking, in any case we have proficient **dissertation service**s who give marvelous work affiliations. You’re at the ideal spot and that too at the ideal time since we have a markdown on the all out of our creation relationship at TheWritingPlanet. Subsequently, it’s the best an ideal open entry for you to benefit of our affiliations while you discharge your anxiety by chilling. In any case, it is commonly your decision to do it without anyone’s help or select an expert to do it for you.

You comprehend that a recommendation or hypothesis is unquestionably new for you, and you’ll need to battle while guiding it, so it will require an enormous heap of effort for you to begin and thusly finish it. Do you think you have great event to do it? Or of course plainly would you have the decision to do it as enough as an expert would do it? Contemplating everything, you’ll find your answer when you utilize TheWritingPlanet’s piece benefits that will help you in creation your hypothesis, proposition, or reference paper. Considering everything, remember you take hypothesis help from our association. Considering, you’ll be getting the help of a Ph.D. degree holder who has enormous combination with making a few affiliations and proposal papers beginning at now. It would other than help on the off chance that you didn’t stress over passing marks since you will accomplish the most raised of all. Do you know why? This is on the grounds that our party of journalists wires Ph.D. holders who were top graders in their particular fields and schools. Accordingly, you will get ensured results at TheWritingPlanet.

Is it affirmed that you are pushed considering the way that your cutoff time is moving closer?

Cutoff time a basic bit of the time changes into a shocking dream for understudies, and they everything thought about breeze up zeroing in on themselves. It moreover causes authentic clinical issues, for example, prepared assaults and dread assaults. Thinking about these parts, quite a while back, we started our trim office, which has appeared at the raised level at this point. In a little while, starting at now, the understudies are in an unclear condition, and we are their confirmations.

Teachers don’t like that the time they give for finishing the speculation isn’t sufficient for an understudy considering the way that an epic piece of the understudies have a colossal heap of different things on their can list. Some of them need to consider their family; some need to deal with their positions while some sit back pushing. Thusly, if your cutoff time is drawing nearer soon, you’re so far in no disposition regardless, your suggestion paper with no other individual, by then you’ll truly need to pick and hand over your undertaking to us. We won’t let you gobble up additional time since it continues moving endlessly from our hands, and we don’t have anything left back near the end.

We can help you at essential occasions when you perceive its absolutely unfathomable left you can do your article or proposition paper. On the off chance that you complete these assignments by us, you’ll clear as can be get your scholastics direct on target with surprising outcomes. Our makers are the best in their fields, and they outfit our customers with the best affiliations.

#custom-writing-services #write-my-paper #the-writing-planet #cheap-dissertation #the-writing-planet