gdstruct - GDS - General Data Structure

A General Data Structure (GDS) is a universal, composable data structure, used to store any kind of data.
This could be for example the definition of configurations, specifications and data sets. Typical usage is the definition of configurations, specifications and data sets. The GDS language is a special DSL (domain specific language) for defining general data structures. It uses a succinct, indentation-sensitive syntax which makes data representation clear and readable. The building blocks for general data structures are hashes and arrays.

Installation

gem install gdstruct

A Short Example

require "gdstruct"

h = GDstruct.c( ":\n  a val a\n  b val b\n" )

# => h = { a: 'val a', b: 'val b' }

An Introduction

The GDS language uses two basic symbols (: and ,) for the creation of hashes and arrays.

A colon (:) is used to define a hash.
A comma (,) is used to define an array.

Use indentation with two spaces for the definition of elements and for nested structures. Tab characters are not allowed for indentation.

Another Example

:
  caption foo
  credit  bar
  images
    small
      url  http://mywebsite.com/image-small.jpg
      dimensions
        height 500
        width  500
    large
      url  http://mywebsite.com/image-large.jpg
      dimensions
        height 500
        width  500
  videos
    small
      preview  http://mywebsite.com/video.m4v
      dimensions
        height 300
        width  400

transforms to

{
  :caption => 'foo',
  :credit => 'bar',
  :images => {
    :small => {
      :url => 'http://mywebsite.com/image-small.jpg',
      :dimensions => {
        :height => 500,
        :width => 500
      }
    },
    :large => {
      :url => 'http://mywebsite.com/image-large.jpg',
      :dimensions => {
        :height => 500,
        :width => 500
      }
    },
  },
  :videos => {
    :small => {
      :preview => 'http://mywebsite.com/video.m4v',
      :dimensions => {
        :height => 300,
        :width => 400
      }
    }
  }
}

General Example

,
  v1
  : k2 v2
  : k31 v31 | k32 v32 | k33 v33
    k34 v34
    k35 v35 | k36 v36 
  : 
    k41 v41
    k42 v42
    k43,
    k44, 1 | 2 | 3
      4 | 5
      6
      7
      8 | 9
      :k441 v441
  v5

# =>  [ 'v1', { k2: 'v2' }, { k31: 'v31', k32: 'v32', k33: 'v33', k34: 'v34', k35: 'v35', k36: 'v36' }, 
        { k41: 'v41', k42: 'v42', k43: [], k44: [1, 2, 3, 4, 5, 6, 7, 8, 9, { k441: 'v441' } ] }, 'v5' ] 

Motivation and Features

  • the focus is on the essential data
  • structure and hierarchy is expressed using indentation (whitespace-sensitive) - avoids curly braces and square brackets
  • uses a succinct and minimalist syntax - tries to avoid unnecessary characters
  • in many cases colons, commas and quotes are not necessary
  • less text makes data clearer and more readable
  • for configuration and specification - replacement for XML, JSON, YAML
  • for data/database seeding
  • less text and less potential errors using schema definitions
  • supports block comments, which could be nested
  • allows also the definition of hash and array structures in a kind of restricted classic Ruby like syntax
  • provides an alternative for Ruby hash and array definition without using eval(); can be used as a protection against code injection vulnerabilities, e.g. on web servers

Schema specifiers

Schema specifiers can be used to predefine the keys of a hash or subhash. When you specify the values you no longer need to name the key for each value. This facilitates the input for hashes and prevents typos for keys.
In combination with the pipe symbol (|), which allows to define multiple values on a single line, this features a slim and clearly arranged, table-like style for data.

$country(name,capital,area,population,vehicleRegistrationCode,iso3166code,callingCode)
, $country   /*
    name            capital            area (km^2)   population      vehicleRegistrationCode   iso3166code   callingCode
  ---------------------------------------------------------------------------------------------------------------------------- */
  : Deutschland   | Berlin           |    357_385  |    82_521_653 | D                       | DE          | 49
  : USA           | Washington, D.C. |  9_833_520  |   325_719_178 | USA                     | US          | 1
  : China         | Beijing          |  9_596_961  | 1_403_500_365 | CHN                     | CN          | 86
  : India         | New Dehli        |  3_287_469  | 1_339_180_000 | IND                     | IN          | 91
  : Austria       | Vienna           |     83_878  |     8_822_267 | A                       | AT          | 43
  : Denmark       | Copenhagen       |     42_921  |     5_748_769 | DK                      | DK          | 45
  : Canada        | Ottawa           |  9_984_670  |    36_503_097 | CDN                     | CA          | 1
  : France        | Paris            |    643_801  |    66_991_000 | F                       | FR          | 33
  : Russia        | Moscow           | 17_075_400  |   144_526_636 | RUS                     | RU          | 7

transforms to

[
  { :name=>"Deutschland", :capital=>"Berlin", :area=>357385, :population=>82521653, :vehicleRegistrationCode=>"D", :iso3166code=>"DE", :callingCode=>49 },
  { :name=>"USA", :capital=>"Washington, D.C.", :area=>9833520, :population=>325719178, :vehicleRegistrationCode=>"USA", :iso3166code=>"US", :callingCode=>1 },
  { :name=>"China", :capital=>"Beijing", :area=>9596961, :population=>1403500365, :vehicleRegistrationCode=>"CHN", :iso3166code=>"CN", :callingCode=>86 },
  { :name=>"India", :capital=>"New Dehli", :area=>3287469, :population=>1339180000, :vehicleRegistrationCode=>"IND", :iso3166code=>"IN", :callingCode=>91 },
  { :name=>"Austria", :capital=>"Vienna", :area=>83878, :population=>8822267, :vehicleRegistrationCode=>"A", :iso3166code=>"AT", :callingCode=>43 },
  { :name=>"Denmark", :capital=>"Copenhagen", :area=>42921, :population=>5748769, :vehicleRegistrationCode=>"DK", :iso3166code=>"DK", :callingCode=>45 },
  { :name=>"Canada", :capital=>"Ottawa", :area=>9984670, :population=>36503097, :vehicleRegistrationCode=>"CDN", :iso3166code=>"CA", :callingCode=>1 },
  { :name=>"France", :capital=>"Paris", :area=>643801, :population=>66991000, :vehicleRegistrationCode=>"F", :iso3166code=>"FR", :callingCode=>33 },
  { :name=>"Russia", :capital=>"Moscow", :area=>17075400, :population=>144526636, :vehicleRegistrationCode=>"RUS", :iso3166code=>"RU", :callingCode=>7 }
] 

Futher Information

You will find futher information here https://urasepandia.de/gds.html

Maintainer

Uli Ramminger [email protected]

Copyright

Copyright (c) 2018 Ulrich Ramminger

See MIT-LICENSE for further details.