Pular para o conteúdo

Biblioteca publicável

Validador de placas de veículo — com relay, erro que diz o motivo e o pacote pronto para o registro.

Uma biblioteca é um projeto sem main: quem roda é o código de outra pessoa. Isso muda três coisas — o que é público precisa ser declarado, o erro precisa servir a quem não leu o seu código, e a versão passa a ser uma promessa.

PeçaO que ela exercita
relaya superfície pública, e só ela
o vault de resultado{ok, motivo} em vez de no
dataforge packo tarball reprodutível
o teste pelo nome do pacoteadopt placa, como o usuário faria

Estrutura#

text
placa/
  forge.toml
  src/
    main.df        relay validar, formatar, tipo
  tests/
    placa_test.df  adopt placa  (pelo nome!)
  README.md
forge.toml
[project]
name = "placa"
version = "1.0.0"
description = "Valida e formata placas brasileiras (antiga e Mercosul)"
entry = "src/main.df"
license = "MIT"
dataforge = ">=1.1"

[dependencies]

O núcleo#

Este bloco roda sozinho — copie para um arquivo e rode dataforge run. Ele termina com assert, e é assim que esta página é conferida a cada build.

src/main.df
// Antiga: ABC-1234. Mercosul: ABC1D23.
steady ANTIGA := "^[A-Z]{3}-?[0-9]{4}$"
steady MERCOSUL := "^[A-Z]{3}[0-9][A-Z][0-9]{2}$"

action _limpar(texto):
    yield texto.trim().upper().replace(" ", "")

action tipo(texto):
    t := _limpar(texto)
    given regex_test(MERCOSUL, t):
        yield "mercosul"
    given regex_test(ANTIGA, t):
        yield "antiga"
    yield void

action validar(texto):
    given texto is void or _limpar(texto) is "":
        yield {"ok": no, "motivo": "placa vazia"}
    t := _limpar(texto)
    given len(t.replace("-", "")) is not 7:
        yield {"ok": no, "motivo": $"tem {len(t.replace('-', ''))} caracteres, e uma placa tem 7"}
    given tipo(t) is void:
        yield {"ok": no, "motivo": "nao e nem o formato antigo (ABC-1234) nem o Mercosul (ABC1D23)"}
    yield {"ok": yes, "motivo": "", "tipo": tipo(t)}

action formatar(texto):
    t := _limpar(texto).replace("-", "")
    given tipo(t) is "antiga":
        yield t[0:3] + "-" + t[3:]
    yield t

relay validar, formatar, tipo

assert validar("abc1d23")["tipo"] is "mercosul"
assert formatar("abc1234") is "ABC-1234"
assert "7" in validar("AB123")["motivo"]
assert not validar("ABC12D3")["ok"]
out validar("ABC12D3")["motivo"]

O teste#

No projeto, a regra mora em src/ e o teste a importa pelo caminho relativo — dataforge test tests/ descobre o arquivo sozinho.

tests/placa_test.df
adopt placa as P

crucible "placa":
    trial "o motivo diz o que esta errado":
        expect P.validar("")["motivo"] is "placa vazia"

    trial "_limpar nao e publico":
        expect(lambda => P._limpar("x")).to_raise()

As decisões#

DecisãoSem ela
relay explícitoo _limpar interno vira contrato e nunca mais pode mudar
o motivo em vez de noo formulário de quem usa diz “placa inválida” e mais nada
o teste pelo nome do pacotea biblioteca funciona no repositório e quebra instalada
license no manifestoa empresa de quem instala não pode usar

Para ir além#

Volte para todos os tipos de projeto.