Project

xeme

0.0
No release in over a year
Standard structure for reporting results of an operation.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 0.9.6
 Project Readme

Xeme

Xeme provides a common format for returning the results of a process. First we'll look at the Xeme format, which is language independent, then we'll look at how the Xeme gem implements the format.

Xeme structure

The Xeme structure can be used by any software, Ruby or otherwise, as a standard way to report results. A Xeme structure can be stored in any format that recognizes hashes, arrays, strings, numbers, booleans, and null. Such formats include JSON and YAML. In these examples we'll use JSON.

A xeme can be as simple as an empty hash:

{}

That structure indicates no errors, and, in fact, no details at all. However, it also does not explicitly indicate success. In the absence of a defined value of true or false, the result should be considered either undetermined or failed.

To indicate a successful operation, a xeme must have an explicit success element:

{"success":true}

A xeme can be marked as explicitly failed:

{"success":false}

Any truthy value for success is considered to indicate success. So, for example, the following xeme should be considered to indicate success.

{"success":{}}

A xeme may contain other arbitrary information. This is useful if you need more information than just a success or failure.

{"success":true, "tags":["a", "b"]}

Metainformation

A xeme may contain a meta element. The meta element can contain a timestamp, UUID, description, or other meta information.

{
  "success":true,
  "meta": {
    "timestamp": "2023-06-21T08:57:56+00:00",
    "uuid": "e11b668c-0823-4b70-aa28-5ac83757a37c",
    "description": "directory tests"
  }
}

meta can contain any arbitrary information you want, but several elements, if present, should follow some standards.

key description
id A string, typically without spaces.
description A short description of the xeme as a string.
timestamp Timestamp in a standard ISO 8601 format.
UUID A UUID.

Nested xemes

A xeme represents the results of a single process. However, a xeme can also contain nested xemes which provide information about sub-processes. In this sense, a xeme can be considered as the final results of the xemes nested within it.

Child xemes are contained in the nested array.

{
  "success":true,
  "meta": {"id":"directory"},
  "nested":[
    {"success":true, "meta": {"id":"database-connection"}},
    {"success":true, "meta": {"id":"update"}}
  ]
}

Nested xemes can themselves have nested xemes, forming a tree of process results.

{
  "success":true,
  "meta": {"id":"database"},
  "nested": [
    {
      "success":true,
      "meta": {"id":"database-connection"},
      "nested": [
        {"success":true, "meta":{"id":"initialization"}},
        {"success":true, "meta":{"id":"disconnection"}}
      ]
    }
  ]
}

Resolution

Xeme operates on the concept of "least successful outcome". A xeme cannot represent more success than its descendent xemes. So, for example, the following structure contains conflicts:

{
  "success":true,
  "nested":[
    {"success":false}
  ]
}

It is necessary to resolve these conflicts before the xeme can be considered valid. A conforming processor should implement the following rules:

  • If a xeme is marked as failure, all of its ancestor xemes should be marked as failed. So the example above would be resolved as follows:
{
  "success":false,
  "nested":[
    {"success":false}
  ]
}

A process can be marked as failed regardless of its nested xemes. So there is no conflict in the following structure.

{
  "success":false,
  "nested":[
    {"success":true}
  ]
}
  • If a xeme's success is null, then all its ancestors' success values must be set to null if they are not already set to false. The following structure is invalid.
{
  "success":true,
  "nested":[
    {"success":null}
  ]
}

It should be resolved as follows:

{
  "success":null,
  "nested":[
    {"success":null}
  ]
}

Advisory and promise xemes

Three types of Xemes operate on a different ruleset than standard xemes. Those types are warnings, notes, and promises. They are indicated by the type property:

{"type": "warning"}

Warnings and notes

Warnings and notes provide advisory information about a process. They have no affect on the success/failure determination. Warnings provide information about non-fatal problems in a prosess. Notes do not indicate problems of any kind and simply provide whatever arbitrary information might be useful. Advisory xemes should not have success properties. So, for example, the following structure is valid, even though the nested advisory xemes do not have success properties.

{
  "success":true,
  "nested":[
    {"type":"warning", "id":"invalid-setting"},
    {"type":"note", "id":"database-connected"}
  ]
}

Advisory xemes can have nested xemes. However, all descendents of an advisory xeme should themselves be advisory.

Promises

A promise xeme indicates that the success/failure of a process has yet to be determined. A promise should have a success value of null, unless it has also has a truthy value in supplanted. For example, the following xemes are valid:

{ "type":"promise" }
{ "type":"promise", "supplanted":true, "success": true }
{ "type":"promise", "supplanted":"2023-06-22T06:28:43+0000", "success": true }

Typically, a promise should have an indication of how the promise can be resolved. For example, the following xeme is a promise, with further information to indicate a URI where the final result can be determined, and how soon to query that URI.

{
  "type":"promise",
  "uri": "https://example.com/20435t",
  "delay": 6000
}

No standards are defined on how promises should provide such information. A substandard may be defined down the road.

Best practice is that when a promise xeme is supplanted, it should have a nested xeme that provides the final success/failure of the process.

{
  "success": true,
  "supplanted": true,
  "type":"promise",
  "uri": "https://example.com/20435t",
  "delay": 6000,
  
  "nested": [
    {"success":true}
  ]
}