A Form Encoding & Decoding Package for Go

Related tags

Forms form
Overview

form

A Form Encoding & Decoding Package for Go, written by Alvaro J. Genial.

Build Status GoDoc

Synopsis

This library is designed to allow seamless, high-fidelity encoding and decoding of arbitrary data in application/x-www-form-urlencoded format and as url.Values. It is intended to be useful primarily in dealing with web forms and URI query strings, both of which natively employ said format.

Unsurprisingly, form is modeled after other Go encoding packages, in particular encoding/json, and follows the same conventions (see below for more.) It aims to automatically handle any kind of concrete Go data value (i.e., not functions, channels, etc.) while providing mechanisms for custom behavior.

Status

The implementation is in usable shape and is fairly well tested with its accompanying test suite. The API is unlikely to change much, but still may. Lastly, the code has not yet undergone a security review to ensure it is free of vulnerabilities. Please file an issue or send a pull request for fixes & improvements.

Dependencies

The only requirement is Go 1.2 or later.

Usage

import "github.com/ajg/form"
// or: "gopkg.in/ajg/form.v1"

Given a type like the following...

type User struct {
	Name         string            `form:"name"`
	Email        string            `form:"email"`
	Joined       time.Time         `form:"joined,omitempty"`
	Posts        []int             `form:"posts"`
	Preferences  map[string]string `form:"prefs"`
	Avatar       []byte            `form:"avatar"`
	PasswordHash int64             `form:"-"`
}

...it is easy to encode data of that type...

func PostUser(url string, u User) error {
	var c http.Client
	_, err := c.PostForm(url, form.EncodeToValues(u))
	return err
}

...as well as decode it...

func Handler(w http.ResponseWriter, r *http.Request) {
	var u User

	d := form.NewDecoder(r.Body)
	if err := d.Decode(&u); err != nil {
		http.Error(w, "Form could not be decoded", http.StatusBadRequest)
		return
	}

	fmt.Fprintf(w, "Decoded: %#v", u)
}

...without having to do any grunt work.

Field Tags

Like other encoding packages, form supports the following options for fields:

  • `form:"-"`: Causes the field to be ignored during encoding and decoding.
  • `form:"<name>"`: Overrides the field's name; useful especially when dealing with external identifiers in camelCase, as are commonly found on the web.
  • `form:",omitempty"`: Elides the field during encoding if it is empty (typically meaning equal to the type's zero value.)
  • `form:"<name>,omitempty"`: The way to combine the two options above.

Values

Simple Values

Values of the following types are all considered simple:

  • bool
  • int, int8, int16, int32, int64, rune
  • uint, uint8, uint16, uint32, uint64, byte
  • float32, float64
  • complex64, complex128
  • string
  • []byte (see note)
  • time.Time
  • url.URL
  • An alias of any of the above
  • A pointer to any of the above

Composite Values

A composite value is one that can contain other values. Values of the following kinds...

  • Maps
  • Slices; except []byte (see note)
  • Structs; except time.Time and url.URL
  • Arrays
  • An alias of any of the above
  • A pointer to any of the above

...are considered composites in general, unless they implement custom marshaling/unmarshaling. Composite values are encoded as a flat mapping of paths to values, where the paths are constructed by joining the parent and child paths with a period (.).

(Note: a byte slice is treated as a string by default because it's more efficient, but can also be decoded as a slice—i.e., with indexes.)

Untyped Values

While encouraged, it is not necessary to define a type (e.g. a struct) in order to use form, since it is able to encode and decode untyped data generically using the following rules:

  • Simple values will be treated as a string.
  • Composite values will be treated as a map[string]interface{}, itself able to contain nested values (both scalar and compound) ad infinitum.
  • However, if there is a value (of any supported type) already present in a map for a given key, then it will be used when possible, rather than being replaced with a generic value as specified above; this makes it possible to handle partially typed, dynamic or schema-less values.

Zero Values

By default, and without custom marshaling, zero values (also known as empty/default values) are encoded as the empty string. To disable this behavior, meaning to keep zero values in their literal form (e.g. 0 for integral types), Encoder offers a KeepZeros setter method, which will do just that when set to true.

Unsupported Values

Values of the following kinds aren't supported and, if present, must be ignored.

  • Channel
  • Function
  • Unsafe pointer
  • An alias of any of the above
  • A pointer to any of the above

Custom Marshaling

There is a default (generally lossless) marshaling & unmarshaling scheme for any concrete data value in Go, which is good enough in most cases. However, it is possible to override it and use a custom scheme. For instance, a "binary" field could be marshaled more efficiently using base64 to prevent it from being percent-escaped during serialization to application/x-www-form-urlencoded format.

Because form provides support for encoding.TextMarshaler and encoding.TextUnmarshaler it is easy to do that; for instance, like this:

import "encoding"

type Binary []byte

var (
	_ encoding.TextMarshaler   = &Binary{}
	_ encoding.TextUnmarshaler = &Binary{}
)

func (b Binary) MarshalText() ([]byte, error) {
	return []byte(base64.URLEncoding.EncodeToString([]byte(b))), nil
}

func (b *Binary) UnmarshalText(text []byte) error {
	bs, err := base64.URLEncoding.DecodeString(string(text))
	if err == nil {
		*b = Binary(bs)
	}
	return err
}

Now any value with type Binary will automatically be encoded using the URL variant of base64. It is left as an exercise to the reader to improve upon this scheme by eliminating the need for padding (which, besides being superfluous, uses =, a character that will end up percent-escaped.)

Keys

In theory any value can be a key as long as it has a string representation. However, by default, periods have special meaning to form, and thus, under the hood (i.e. in encoded form) they are transparently escaped using a preceding backslash (\). Backslashes within keys, themselves, are also escaped in this manner (e.g. as \\) in order to permit representing \. itself (as \\\.).

(Note: it is normally unnecessary to deal with this issue unless keys are being constructed manually—e.g. literally embedded in HTML or in a URI.)

The default delimiter and escape characters used for encoding and decoding composite keys can be changed using the DelimitWith and EscapeWith setter methods of Encoder and Decoder, respectively. For example...

package main

import (
	"os"

	"github.com/ajg/form"
)

func main() {
	type B struct {
		Qux string `form:"qux"`
	}
	type A struct {
		FooBar B `form:"foo.bar"`
	}
	a := A{FooBar: B{"XYZ"}}
	os.Stdout.WriteString("Default: ")
	form.NewEncoder(os.Stdout).Encode(a)
	os.Stdout.WriteString("\nCustom:  ")
	form.NewEncoder(os.Stdout).DelimitWith('/').Encode(a)
	os.Stdout.WriteString("\n")
}

...will produce...

Default: foo%5C.bar.qux=XYZ
Custom:  foo.bar%2Fqux=XYZ

(%5C and %2F represent \ and /, respectively.)

Limitations

  • Circular (self-referential) values are untested.

Future Work

The following items would be nice to have in the future—though they are not being worked on yet:

  • An option to treat all values as if they had been tagged with omitempty.
  • An option to automatically treat all field names in camelCase or underscore_case.
  • Built-in support for the types in math/big.
  • Built-in support for the types in image/color.
  • Improve encoding/decoding by reading/writing directly from/to the io.Reader/io.Writer when possible, rather than going through an intermediate representation (i.e. node) which requires more memory.

(Feel free to implement any of these and then send a pull request.)

Related Work

License

This library is distributed under a BSD-style LICENSE.

Issues
  • Intentional special casing of periods in form keys limits real-world usage

    Intentional special casing of periods in form keys limits real-world usage

    Due to the intentional special casing of periods within form, any API which uses periods in a form field cannot be interacted with without some hacks. For example, the fastly API utilizes periods in their form fields: https://docs.fastly.com/api/config#settings_9740ff4ac0c1777f455274c4850ece23

    The go-fastly library attempted to work around this by manually ripping out the generated escapes, but that leads to other things being unintentionally ripped out, as noted in this case: https://github.com/sethvargo/go-fastly/issues/11

    Is there any workaround for interacting with forms which have periods in their form keys?

    enhancement resolved 
    opened by alienth 5
  • keys with periods in them

    keys with periods in them

    A particular third-party API I wish to contact used periods in the key names. I have the keys in my structs labelled as such:

    type whatever struct { CleanupReturnCleaned bool form:"cleanup.returnCleaned" }

    but when I run form.EncodeToString() I get: cleanup%5C.returnCleaned=true

    I've read the documentation in the Readme and have tried escaping the period with a back slash but that doesnt seem to have the desired effect. Am I misreading the readme, or is this not possible using ajg/form?

    Cheers!

    resolved 
    opened by JalfResi 4
  • Behavior of isEmptyValue

    Behavior of isEmptyValue

    The implementation of isEmptyValue makes encoding certain structs a bit non-intuitive. Similar to the discussion here, I am trying to encode a 0 in a request.

    I would expect the following code to result in "num=0&name=test" but instead I end up with "num=&name=test" even though my value does "exist".

    package main
    
    import (
        "bytes"
        "github.com/ajg/form"
        "log"
    )
    
    type Thing struct {
        String  string `form:"name,omitempty"`
        Integer *uint  `form:"num,omitempty"`
    }
    
    func main() {
    
        a_num := uint(0)
        u := Thing{"test", &a_num}
        buf := new(bytes.Buffer)
        if err := form.NewEncoder(buf).DelimitWith('|').Encode(u); err != nil {
            log.Printf("[ERR] %s", err)
        }
        body := buf.String()
        log.Printf("[DEBUG] %s", body)
    
    }
    
    enhancement resolved 
    opened by keshavdv 3
  • Possibility of not indicate the index in the form html

    Possibility of not indicate the index in the form html

    Hi, I have this: type Film struct { Genres []string Topics []string }

    I am obliged to indicate the index of slice in the input form:

    Is possible NOT indicate the index and only leave "Topics"? With gorilla/schema it is possible, but gorilla/schema, in general, is much more limited...

    Thanks!

    Best, Emilio

    opened by emilgpa 3
  • Feature Request: File uploads

    Feature Request: File uploads

    It would be nice to have the ability to encode files in the form data.

    For example, we could have a special struct tag that indicates this field represents a file path.

    opened by CyrusJavan 2
  • Proposal: Support for Reset

    Proposal: Support for Reset

    It would be useful for my use case if both the encoder and decoder structs exposed a Reset method which allowed changing the underlying io.Writer or io.Reader without having to create new instances. This makes it possible to use sync.Pool for example to manage a set of instances. The implementation would be trivial given that they don't have state other than the writer or reader. Would you consider a PR that added these? I'm thinking something like:

    in decode.go:

    func (d *decoder) Reset(r io.Reader) {
        d.r = r
    }
    

    in encode.go

    func (e *encoder) Reset(w io.Writer) {
        e.w = w
    }
    
    enhancement question 
    opened by raphael 2
  • Proposal: Produce efficient errors instead raw panic message

    Proposal: Produce efficient errors instead raw panic message

    I always like to check my form fields to see if their values are convertible to needed types and if not then inform the user about invalid fields. form produces *errors.errorString and this is not useful when generating error responses for this purpose.

    What about defining a new error type such as below to give more control over them

    e.g.

    type Error []Field
    
    func (e Error) Error() string {
      return "todo"
    }
    
    type Field struct {
      Name string // tag name e.g. time from form:"time"
      Message string // original error message 
      Type reflect.Type // point out the expected type so we can generate even more graceful error messages by checking this e.g. "time must be a UTC date"
      SliceIndex int // point out the index if an invalid Type placed in a slice except []byte
    }
    

    A dummy usage:

    type Post struct {
      Time time.Time `form:"time"`
    }
    
    var p Post
    err := form.DecodeValues(&p, url.Values{"time", []string{"AnInvalidDate"}})
    if (err.(form.Error))[0].Type == form.TimeType {
     // so I can response a nice error message to user like:
     // HTTP 400
     // {"message": "Invalid Form Data", fields: {"time": "must be UTC formatted"}}
    }
    

    I'd like to implement this if you'll consider accepting the PR

    enhancement 
    opened by ilgooz 2
  • two features

    two features

    EncodeToString, remain 'null' value:

    {“test1”: 0, “test2”: false} EncodeToString
    from
    test1=&test2=
    change to
    test1=0&test2=false
    

    fieldInfo: using 'json' tag as second choice: using 'form' as default tag, using 'json' tag when there's no 'form' tag.

    opened by godblesshugh 1
  • Add flags to ignore case and ignore unknown keys

    Add flags to ignore case and ignore unknown keys

    This pull request adds two methods to the decoder{} struct: IgnoreUnknownKeys(bool) and IgnoreCase(true).

    The idea of IgnoreUnknownKeys is similar to the method with the same name in gorilla/schema: https://github.com/gorilla/schema/blob/master/decoder.go#L53 Also, setting it to true makes this lib more similar to how encoding/json handle unknown keys.

    IgnoreCase will allow matching struct fields with case insensitive names. This is only used as a fallback, if an exact match exists in the struct it will be given priority over a case insensitive match.

    To allow using these flags with DecodeValues and DecodeString I decided to add them as methods to the decoder struct, the reader is ignored if they are called. The still also exist as package functions and so this change shouldn't break anyone using this library.

    Please let me know if there's anything you'd like me to change on this PR.

    opened by cezarsa 1
  • Can decode/encode anonymous fields

    Can decode/encode anonymous fields

    Hi! In the app that I created found a problem. I use a lot of this library, it allow so much fields but not anonymous fields. For example, i have in my project a two structs:

    type Length struct {
        Title        map[string]string `json:"title"`
        Release  map[string]string `json:"release,omitempty"`
        Genres   Genre                  `json:"genres"`
        Topics    []string                 `json:"genres"`
    }
    
    type FilmBasedEpisodes struct {
        Length
        Channel  Channel
        Seasons  []Season
    }
    

    But when I want do this:

    ....
    r.ParseMultipartForm(maxMemory)
    dataFormHTML := r.Form
    film := FilmBasedEpisodes{}
    err := form.DecodeValues(&film, dataFormHTML)
    ....
    

    The content of dataFormHTML is, for example, like this:

    "Title.US":"Six Feet Under", "Title.ES": "A dos metros bajo tierra", "Channel.Original":"HBO"
    

    The error from ajg.form in go compiler is : Title doesn't exist in struct main.FilmBasedEpisodes

    I understand that the library not is compatible with anonymous fields, right? If I wrong, then, how I do it?

    Best, Emilio

    opened by emilgpa 1
  • Fix empty struct checks after change in Go 1.16

    Fix empty struct checks after change in Go 1.16

    The previous verification for empty structs was invalid and only worked by chance for structs with no fields. After the change in Go 1.16 described in https://github.com/golang/go/issues/43993 this verification stopped working.

    This PR changes how empty structs are handled and also adds new test cases to ensure that this behavior is now consistent.

    opened by cezarsa 0
  • Tests are failing on Go 1.17:

    Tests are failing on Go 1.17: "invalid semicolon separator in query"

    It looks like the tests are failing on Go 1.17 and up around parsing semicolons.

    There are a couple ways to resolve - one of them is using the Go handler: https://pkg.go.dev/net/http#AllowQuerySemicolons

    Other suggestions: https://golangshowcase.com/question/invalid-semicolon-separator-in-query-after-go-1-17

    ➜  form git:(master) ✗ go test ./...
    --- FAIL: TestDecodeString (0.00s)
        decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
        decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
        decode_test.go:17: DecodeString(";C=42%2B6.6i;A.0=x;M.Bar=8;F=6.6;A.1=y;R=8734;A.2=z;Zs.0.Qp=33_44;B=true;M.Foo=7;T=2013-10-01T07:05:34.000000088Z;E.Bytes1=%00%01%02;Bytes2=%03%04%05;Zs.0.Q=11_22;Zs.0.Z=2006-12-01;M.Qux=9;life=42;S=Hello,+there.;P\\.D\\\\Q\\.B.A=P/D;P\\.D\\\\Q\\.B.B=Q-B;U=http%3A%2F%2Fexample.org%2Ffoo%23bar;"): invalid semicolon separator in query
    --- FAIL: TestDecodeValues (0.00s)
    panic: invalid semicolon separator in query [recovered]
            panic: invalid semicolon separator in query
    FAIL
    
    opened by josephspurrier 0
  • Serialize composite []string with empty square brackets

    Serialize composite []string with empty square brackets

    👋🏻 I have an API that expects data to be sent like so:

    services[]=A&services[]=B
    

    How can I achieve this?

    Currently the default behaviour appears to number each element within the slice.

    I see there's a DelimitWith method but that doesn't quite achieve what I need (e.g. DelimitWith('|')):

    services|0=A&services|1=B
    

    Is there a custom unmarshal method I can define that might help encode the data how I need it?

    Thanks!

    opened by Integralist 2
  • Remove test cases that are no longer valid with go 1.17

    Remove test cases that are no longer valid with go 1.17

    As of go 1.17, the net/http and net/url packages no longer accept ';' as a valid separator. See https://golang.org/doc/go1.17#semicolons for more information.

    In order to build this package with go 1.17 and keep it in Ubuntu, the test cases that use ';' as a separator should be removed.

    opened by jawn-smith 2
  • Adding Power support(ppc64le) with continuous integration/testing so that project stays architecture independent.

    Adding Power support(ppc64le) with continuous integration/testing so that project stays architecture independent.

    Please review and merge the changes ,This is part of the Ubuntu distribution for ppc64le. This helps us simplify testing later when distributions are re-building and re-releasing. For more info tag @gerrith3.

    opened by asellappen 1
  • Fails to decode struct if field is missing

    Fails to decode struct if field is missing

    The library fails to decode a struct if field is missing.

    E.g. I do have a struct

    type TokenExchange struct {
      Type string `form:"grant_type"`
      Code string `form:"code"`
    }
    

    The input string to parse

    grant_type=authorization_code&code=xxx&client_id=xxx
    

    The library fails to decode string with an error

    client_id doesn't exist in main.TokenExchange
    

    I would expect that library skips client_id.

    opened by fogfish 1
Releases(v1.5.1)
  • v1.5.1(Aug 22, 2016)

    v1.5.1 Notes

    Miscellaneous

    • SemVer-friendlier tag with explicit patch number per issue #18.
    • Minor Travis CI build configuration tweaks re: pull request #17.
    Source code(tar.gz)
    Source code(zip)
Owner
Alvaro J. Genial
Alvaro J. Genial
A lightweight go library for parsing form data or json from an http.Request.

Forms Forms is a lightweight, but incredibly useful go library for parsing form data from an http.Request. It supports multipart forms, url-encoded fo

Alex Browne 131 May 8, 2022
Go module for encoding structs into URL query parameters

qs Package sonh/qs encodes structs into url.Values. Installation go get github.com/sonh/qs Usage import ( "github.com/sonh/qs" ) Package qs export

Son Huynh 62 Jun 12, 2022
go-eexcel implements encoding and decoding of XLSX like encoding/json

go-eexcel go-eexcel implements encoding and decoding of XLSX like encoding/json Usage func ExampleMarshal() { type st struct { Name string `eexce

sago35 0 Dec 9, 2021
Mantil-template-form-to-dynamodb - Receive form data and write it to a DynamoDB table

This template is an example of serverless integration between Google Forms and DynamoDB

Christoph Berger 2 Jan 17, 2022
Go package for decoding and encoding TARGA image format

tga tga is a Go package for decoding and encoding TARGA image format. It supports RLE and raw TARGA images with 8/15/16/24/32 bits per pixel, monochro

Sigrid Solveig Haflínudóttir 30 Mar 5, 2022
Go package containing implementations of efficient encoding, decoding, and validation APIs.

encoding Go package containing implementations of encoders and decoders for various data formats. Motivation At Segment, we do a lot of marshaling and

Segment 848 Jun 15, 2022
MIME mail encoding and decoding package for Go

enmime enmime is a MIME encoding and decoding library for Go, focused on generating and parsing MIME encoded emails. It is being developed in tandem w

James Hillyerd 313 Jun 18, 2022
Package json implements encoding and decoding of JSON as defined in RFC 7159

Package json implements encoding and decoding of JSON as defined in RFC 7159. The mapping between JSON and Go values is described in the documentation for the Marshal and Unmarshal functions

High Performance, Kubernetes Native Object Storage 3 May 10, 2022
A simple, semantic and developer-friendly golang package for encoding&decoding and encryption&decryption

A simple, semantic and developer-friendly golang package for encoding&decoding and encryption&decryption

null 243 Jun 23, 2022
encLib is a simple golang package for quickly encoding and decoding string data in hex

encLib is a simple golang package for quickly encoding and decoding string data in hex

null 0 Nov 1, 2021
? ID3 decoding and encoding library for Go

id3v2 Supported ID3 versions: 2.3, 2.4 Installation go get -u github.com/bogem/id3v2 Usage example package main import ( "fmt" "log" "github.com

Albert Nigmatzianov 247 Jun 29, 2022
Encoding and decoding GeoJSON <-> Go

go.geojson Go.geojson is a package for encoding and decoding GeoJSON into Go structs. Supports both the json.Marshaler and json.Unmarshaler interfaces

Paul Mach 205 Jun 24, 2022
Encoding and decoding for fixed-width formatted data

fixedwidth Package fixedwidth provides encoding and decoding for fixed-width formatted Data. go get github.com/ianlopshire/go-fixedwidth Usage Struct

Ian Lopshire 63 May 8, 2022
Go structure annotations that supports encoding and decoding; similar to C-style bitfields. Supports bitfield packing, self-describing layout parameters, and alignment.

STRUCTure EXtensions structex provides annotation rules that extend Go structures for implementation of encoding and decoding of byte backed data fram

Hewlett Packard Enterprise 51 Apr 19, 2022
A codec for Go structs with support for chainable encoding/decoding hooks.

structool A codec for Go structs with support for chainable encoding/decoding hooks. Features Provide a uniform codec by combining mapstructure and st

Luo Peng 11 Jan 15, 2022
json encoding and decoding

jx Package jx implements encoding and decoding of json [RFC 7159]. Lightweight fork of jsoniter. go get github.com/go-faster/jx Usage and examples Roa

go faster 59 Jun 19, 2022
Some Golang types based on builtin. Implements interfaces Value / Scan and MarshalJSON / UnmarshalJSON for simple working with database NULL-values and Base64 encoding / decoding.

gotypes Some simple types based on builtin Golang types that implement interfaces for working with DB (Scan / Value) and JSON (Marshal / Unmarshal). N

null 0 Feb 12, 2022
GED - Global-purpose Encoding / Decoding library

GED - Global-purpose Encoding / Decoding library This library lets you use common encoding/decoding schemes and allows you to define custom ones. Use

Noémien Kocher 0 Nov 28, 2021
Custom generic HTTP handler providing automatic JSON decoding/encoding of HTTP request/response to your concrete types

gap Custom generic HTTP handler providing automatic JSON decoding/encoding of HTTP request/response to your concrete types. gap.Wrap allows to use the

Ectobit 0 Jan 5, 2022
a package for decode form's values into struct in Go

formam A Go package to decode HTTP form and query parameters. The only requirement is Go 1.10 or later. Features Infinite nesting for maps, structs an

Monoculum 171 Jun 22, 2022
Gookit 721 Jun 29, 2022
A lightweight go library for parsing form data or json from an http.Request.

Forms Forms is a lightweight, but incredibly useful go library for parsing form data from an http.Request. It supports multipart forms, url-encoded fo

Alex Browne 131 May 8, 2022
Simple application written in Go that combines two wordlists and a list of TLDs to form domain names and check if they are already registered.

Domainerator Domainerator was my first Go application. It combines two wordlists (prefixes and suffixes) and a list of TLDs to form domain names and c

Herbert Fischer 26 Nov 1, 2021
a cheat-sheet for mathematical notation in code form

math-as-code Chinese translation (中文版) Python version (English) This is a reference to ease developers into mathematical notation by showing compariso

Jam3 14.2k Jun 29, 2022
a small form factor OpenShift/Kubernetes optimized for edge computing

Microshift Microshift is OpenShift1 Kubernetes in a small form factor and optimized for edge computing. Edge devices deployed out in the field pose ve

Red Hat Emerging Technologies 340 Jun 24, 2022
Forms is a fast, powerful, flexible, sortable web form rendering library written in golang.

forms Description forms makes form creation and handling easy. It allows the creation of form without having to write HTML code or bother to make the

coscms 21 Jun 15, 2022
A command line tool for quickly converting Unix timestamps to human readable form.

stamp A command line tool to quickly format a Unix timestamp in a human-readable form. Installation Go is required to build this software. To just bui

Ricco Førgaard 1 Oct 30, 2021
Microshift is a research project that is exploring how OpenShift1 Kubernetes can be optimized for small form factor and edge computing.

Microshift is a research project that is exploring how OpenShift1 Kubernetes can be optimized for small form factor and edge computing.

Oleg Silkin 0 Nov 1, 2021
An Alert notification service is an application which can receive alerts from certain alerting systems like System_X and System_Y and send these alerts to developers in the form of SMS and emails.

Alert-System An Alert notification service is an application which can receive alerts from certain alerting systems like System_X and System_Y and sen

null 0 Dec 10, 2021