Formato NEON

NEON é um formato de dados estruturados legível por humanos. No Nette, é usado para arquivos de configuração. Também é usado para dados estruturados, como configurações, traduções de idiomas, etc. Experimente.

NEON é a abreviação de Nette Object Notation. É menos complexo e desajeitado que XML ou JSON, mas fornece recursos semelhantes. É muito semelhante ao YAML. A principal vantagem é que o NEON possui as chamadas entidades, graças às quais a configuração dos serviços de DI é tão sexy. E permite indentação com tabulações.

O NEON foi construído desde o início para ser fácil de usar.

Integração

Sintaxe

Um arquivo escrito em NEON geralmente representa um array ou um mapeamento.

Mapeamento

Um mapeamento é um conjunto de pares chave-valor, em PHP seria chamado de array associativo. Cada par é escrito como key: value, o espaço após : é necessário. O valor pode ser qualquer coisa: string, número, booleano, null, sequência ou outro mapeamento.

street: 742 Evergreen Terrace
city: Springfield
country: USA

Em PHP, a mesma estrutura seria escrita como:

[ // PHP
	'street' => '742 Evergreen Terrace',
	'city' => 'Springfield',
	'country' => 'USA',
]

Essa notação é chamada de bloco, porque todos os itens estão em linhas separadas e têm a mesma indentação (neste caso, nenhuma). O NEON também suporta uma representação inline de mapeamento, que é fechada entre chaves, a indentação não desempenha nenhum papel e o separador dos elementos individuais é uma vírgula ou uma nova linha:

{street: 742 Evergreen Terrace, city: Springfield, country: USA}

O mesmo escrito em várias linhas (a indentação não importa):

{
	street: 742 Evergreen Terrace
		city: Springfield, country: USA
}

Em vez de : , também pode ser usado = tanto na notação de bloco quanto na inline:

{street=742 Evergreen Terrace, city=Springfield, country=USA}

Sequência

Sequências são arrays indexados em PHP. São escritas como linhas começando com um hífen - seguido por um espaço. O valor novamente pode ser qualquer coisa: string, número, booleano, null, sequência ou outro mapeamento.

- Cat
- Dog
- Goldfish

Em PHP, a mesma estrutura seria escrita como:

[ // PHP
	'Cat',
	'Dog',
	'Goldfish',
]

Essa notação é chamada de bloco, porque todos os itens estão em linhas separadas e têm a mesma indentação (neste caso, nenhuma). O NEON também suporta uma representação inline de sequência, que é fechada entre colchetes, a indentação não desempenha nenhum papel e o separador dos elementos individuais é uma vírgula ou uma nova linha:

[Cat, Dog, Goldfish]

O mesmo escrito em várias linhas (a indentação não importa):

[
	Cat, Dog
		Goldfish
]

Na representação inline, não é possível usar marcadores de indentação.

Combinações

Os valores de mapeamentos e sequências podem ser outros mapeamentos e sequências. O nível de indentação desempenha o papel principal. No exemplo a seguir, o hífen usado para marcar os itens da sequência tem uma indentação maior que a chave pets, então os itens se tornam o valor da primeira linha:

pets:
   - Cat
   - Dog
cars:
   - Volvo
   - Skoda

Em PHP, a mesma estrutura seria escrita como:

[ // PHP
	'pets' => [
		'Cat',
		'Dog',
	],
	'cars' => [
		'Volvo',
		'Skoda',
	],
]

É possível combinar a notação de bloco e inline:

pets: [Cat, Dog]
cars: [
	Volvo,
	Skoda,
]

Dentro da notação inline, não é mais possível usar a notação de bloco, isso não funciona:

item: [
	pets:
	 - Cat     # ISTO NÃO É POSSÍVEL!!!
	 - Dog
]

No caso anterior, escrevemos um mapeamento cujos elementos eram sequências, agora tentaremos o contrário e criaremos uma sequência contendo mapeamentos:

-
	name: John
	age: 35
-
	name: Peter
	age: 28

Não é necessário que os marcadores estejam em linhas separadas, eles também podem ser colocados desta forma:

- name: John
  age: 35
- name: Peter
  age: 28

Depende de você se alinha as chaves em uma coluna usando espaços ou usa uma tabulação.

Como em PHP a mesma estrutura, ou seja, array, é usada tanto para mapeamentos quanto para sequências, ambos podem ser mesclados. A indentação desta vez é a mesma:

- Cat
street: 742 Evergreen Terrace
- Goldfish

Em PHP, a mesma estrutura seria escrita como:

[ // PHP
	'Cat',
	'street' => '742 Evergreen Terrace',
	'Goldfish',
]

Strings

Strings em NEON podem ser fechadas em aspas simples ou duplas. Mas, como você pode ver, elas também podem ficar sem aspas.

- String em NEON sem aspas
- 'String em NEON em aspas simples'
- "String em NEON em aspas duplas"

Se a string contiver os caracteres # " ' , : = - [ ] { } ( ), que podem ser confundidos com a sintaxe NEON, ela precisa ser fechada entre aspas. Recomendamos o uso de aspas simples, pois nelas não se usa escaping. Se você precisar escrever uma aspa em tal string, duplique-a:

'Aspas '' dentro de uma string em aspas simples'

Aspas duplas permitem usar sequências de escape para escrever caracteres especiais usando barras invertidas \. Todas as sequências de escape como no formato JSON são suportadas, e adicionalmente \_, que é um espaço inseparável, ou seja, \u00A0.

- "\t \n \r \f \b \" \\ \/ \_"
- "\u00A9"

Existem outros casos em que é necessário fechar strings entre aspas:

  • começam ou terminam com espaços
  • parecem números, booleanos ou null
  • NEON as entenderia como datas

Strings Multilinha

Uma string multilinha começa e termina com aspas triplas em linhas separadas. A indentação da primeira linha é ignorada para todas as linhas:

'''
	primeira linha
		segunda linha
	terceira linha
	'''

Em PHP, escreveríamos o mesmo como:

"primeira linha\n\tsegunda linha\nterceira linha" // PHP

Sequências de escape funcionam apenas para strings fechadas em aspas duplas em vez de apóstrofos:

"""
	Copyright \u00A9
"""

Números

NEON entende números escritos na chamada notação científica e também números nos sistemas binário, octal e hexadecimal:

- 12         # inteiro
- 12.3       # float
- +1.2e-34   # número exponencial

- 0b11010    # número binário
- 0o666      # número octal
- 0x7A       # número hexadecimal

Nulos

Null pode ser expresso em NEON usando null ou omitindo o valor. Variantes com a primeira letra maiúscula ou todas as letras maiúsculas também são permitidas.

a: null
b:

Booleanos

Valores lógicos são expressos em NEON usando true / false ou yes / no. Variantes com a primeira letra maiúscula ou todas as letras maiúsculas também são permitidas.

[true, TRUE, True, false, yes, no]

Datas

NEON usa os seguintes formatos para expressar datas e os converte automaticamente em objetos DateTimeImmutable:

- 2016-06-03                  # data
- 2016-06-03 19:00:00         # data & hora
- 2016-06-03 19:00:00.1234    # data & microtempo
- 2016-06-03 19:00:00 +0200   # data & hora & zona
- 2016-06-03 19:00:00 +02:00  # data & hora & zona

Entidades

Uma entidade é uma estrutura que se assemelha a uma chamada de função:

Column(type: int, nulls: yes)

Em PHP, é analisado como um objeto Nette\Neon\Entity:

// PHP
new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true])

Entidades também podem ser encadeadas:

Column(type: int, nulls: yes) Field(id: 1)

O que é analisado em PHP desta forma:

// PHP
new Nette\Neon\Entity(Nette\Neon\Neon::Chain, [
	new Nette\Neon\Entity('Column', ['type' => 'int', 'nulls' => true]),
	new Nette\Neon\Entity('Field', ['id' => 1]),
])

Dentro dos parênteses, aplicam-se as regras para a notação inline usada para mapeamentos e sequências, ou seja, pode ser multilinha e, nesse caso, não é necessário usar vírgulas:

Column(
	type: int
	nulls: yes
)

Comentários

Comentários começam com o caractere # e todos os caracteres seguintes à direita são ignorados:

# esta linha será ignorada pelo interpretador
street: 742 Evergreen Terrace
city: Springfield  # isto também é ignorado
country: USA

Neon versus JSON

JSON é um subconjunto do NEON. Portanto, todo JSON pode ser analisado como NEON:

{
"php": {
	"date.timezone": "Europe\/Prague",
	"zlib.output_compression": true
},
"database": {
	"driver": "mysql",
	"username": "root",
	"password": "beruska92"
},
"users": [
	"Dave", "Kryten", "Rimmer"
]
}

E se omitirmos as aspas?

{
php: {
	date.timezone: Europe/Prague,
	zlib.output_compression: true
},
database: {
	driver: mysql,
	username: root,
	password: beruska92
},
users: [
	Dave, Kryten, Rimmer
]
}

E as chaves e vírgulas?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users: [
	Dave, Kryten, Rimmer
]

As listas com marcadores não são mais legíveis?

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer

Adicionamos comentários?

# config da minha aplicação web

php:
	date.timezone: Europe/Prague
	zlib.output_compression: true  # use gzip

database:
	driver: mysql
	username: root
	password: beruska92

users:
	- Dave
	- Kryten
	- Rimmer

Viva, agora você conhece a sintaxe do NEON!

versão: 3.4