sieve

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 4 Imported by: 0

README

sieve

CI Go Reference

A parser and interpreter for the Sieve mail-filtering language (RFC 5228) in Go, with zero external dependencies (standard library only).

Parsing and evaluation are decoupled from any mailbox model. You Parse a script once into a *Script, adapt your message into the neutral Message type, and call Script.Evaluate with an Executor you implement. The evaluator walks the script, evaluates its tests against the message, and calls your Executor's methods to apply the actions the script selected — how each action maps onto a real mailbox (folder names, flag storage, vacation de-duplication, notification transport) is entirely your concern. The two terminal dispositions, discard and reject, are reported through the returned Outcome.

Supported:

  • Control: if / elsif / else, require, stop.
  • Tests: address, header, envelope, exists, size (:over/:under), body, allof, anyof, not, true/false.
  • Match types: :is, :contains, :matches (glob), and a non-standard :regex. Comparators: i;ascii-casemap (default), i;octet, i;ascii-numeric. Address parts: :all/:localpart/:domain.
  • Actions / extensions: keep, discard, fileinto (+:create), redirect, reject, imap4flags (setflag/addflag/removeflag), vacation, notify.

Parsing is strict about the constructs it understands (so Validate catches real mistakes) but lenient about unknown commands, tests, and tagged arguments, so scripts using extensions this package does not implement still load and run their recognised parts.

Install

go get github.com/rest-mail/go-sieve

Usage

package main

import (
	"fmt"

	"github.com/rest-mail/go-sieve"
)

// mailbox implements sieve.Executor, applying actions to your delivery model.
type mailbox struct{ folder string }

func (m *mailbox) Keep()                              {}
func (m *mailbox) FileInto(folder string, create bool) { m.folder = folder }
func (m *mailbox) Redirect(addr string)               {}
func (m *mailbox) Flag(op string, flags []string)     {}
func (m *mailbox) Vacation(v sieve.Vacation)          {}
func (m *mailbox) Notify(method, message string)      {}

func main() {
	script, err := sieve.Parse(`require "fileinto";
if header :contains "Subject" "invoice" { fileinto "Invoices"; }`)
	if err != nil {
		panic(err)
	}

	msg := &sieve.Message{
		Headers: sieve.Headers{Subject: "Your invoice is ready"},
	}

	mb := &mailbox{}
	outcome := script.Evaluate(msg, mb)
	switch outcome.Disposition {
	case sieve.Discard:
		fmt.Println("discard")
	case sieve.Reject:
		fmt.Println("reject:", outcome.RejectReason)
	default:
		fmt.Println("deliver to:", mb.folder) // "Invoices"
	}
}

Validate a script without running it with sieve.Validate(src).

License

MIT © 2026 rest-mail

Documentation

Overview

Package sieve implements a parser and interpreter for a practical subset of the Sieve mail-filtering language (RFC 5228) plus several widely used extensions (envelope, body, imap4flags, vacation, notify) and a non-standard :regex match type.

Parsing and evaluation are separated from the host's mailbox model. A caller [Parse]s a script once, adapts its message into the neutral Message type, and calls Script.Evaluate with an Executor it implements. The evaluator walks the script, evaluates tests against the message, and calls the Executor's methods to apply the actions the script selected (fileinto, redirect, imap4flags, vacation, notify, keep); the terminal dispositions discard and reject are reported through the returned Outcome. How an action maps onto a real mailbox (folder names, flag storage, vacation de-duplication, notification transport) is entirely the Executor's concern.

Control commands: if / elsif / else, require, stop.

Tests: address, header, envelope, exists, size (:over/:under), body, allof, anyof, not, true/false.

Match types: :is, :contains, :matches (glob with * and ?), and a non-standard :regex extension. Comparators i;ascii-casemap (default), i;octet and i;ascii-numeric. Address parts :all/:localpart/:domain.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Validate

func Validate(script string) error

Validate reports whether a Sieve script is syntactically valid.

Types

type Address

type Address struct {
	Name    string
	Address string
}

Address is a structured email address.

type Attachment

type Attachment struct {
	Size int64
}

Attachment contributes its octet Size to the size test.

type Body

type Body struct {
	ContentType string
	Content     string
	Parts       []Body
}

Body is a (possibly multipart) message body used by the body test and size.

type Disposition

type Disposition int

Disposition is the terminal delivery decision an evaluation reached.

const (
	// Continue means no terminal action fired; deliver honouring whatever
	// actions the Executor recorded.
	Continue Disposition = iota
	// Discard means the script asked to silently drop the message.
	Discard
	// Reject means the script asked to refuse the message (see Outcome.RejectReason).
	Reject
)

type Envelope

type Envelope struct {
	From string
	To   []string
}

Envelope holds the SMTP envelope identities used by the envelope test. The host resolves any override (e.g. a gateway-supplied sender) before populating these fields.

type Executor

type Executor interface {
	// Keep requests explicit delivery to the default mailbox.
	Keep()
	// FileInto delivers into the named folder, creating it when create is set.
	FileInto(folder string, create bool)
	// Redirect forwards the message to addr.
	Redirect(addr string)
	// Flag applies an imap4flags operation ("setflag", "addflag", "removeflag").
	Flag(op string, flags []string)
	// Vacation records a vacation auto-reply request.
	Vacation(v Vacation)
	// Notify records a notification request.
	Notify(method, message string)
}

Executor applies the (non-terminal) actions a Sieve script selects. The host implements it to map each action onto its mailbox/delivery model. Methods are invoked in script order; the terminal actions discard and reject are not Executor methods but are reported via the Outcome returned by Script.Evaluate.

type Headers

type Headers struct {
	Subject    string
	From       []Address
	To         []Address
	Cc         []Address
	Bcc        []Address
	MessageID  string
	InReplyTo  string
	Date       string
	References []string
	Raw        map[string][]string
}

Headers holds the structured and raw headers used by header/address/exists tests. Raw is consulted (case-insensitively) for any header not covered by a structured field, so custom headers such as X-Priority are testable.

type Message

type Message struct {
	Headers     Headers
	Envelope    Envelope
	Body        Body
	Attachments []Attachment
}

Message is the neutral view of an email the evaluator tests against. A host maps its own representation onto this type before evaluating; the evaluator never sees the host's message model.

type Outcome

type Outcome struct {
	Disposition  Disposition
	RejectReason string // set only when Disposition == Reject
}

Outcome is the result of evaluating a script.

type Script

type Script struct {
	// contains filtered or unexported fields
}

Script is a fully parsed Sieve script. Parse it with Parse; evaluate it with Script.Evaluate.

func Parse

func Parse(src string) (*Script, error)

Parse parses a Sieve script into an evaluable Script. It is strict about the constructs it understands and lenient about unknown extensions (see the package overview).

func (*Script) Empty

func (s *Script) Empty() bool

Empty reports whether the script has no executable commands (a nil script, or one consisting only of require/comments).

func (*Script) Evaluate

func (s *Script) Evaluate(msg *Message, exec Executor) Outcome

Evaluate runs the script against msg, invoking exec for each action it selects, and returns the terminal Outcome.

func (*Script) Requires

func (s *Script) Requires() []string

Requires returns the extensions the script declared via "require".

type Vacation

type Vacation struct {
	Days    int
	Subject string
	Body    string
	ReplyTo string
}

Vacation carries the arguments of a matched vacation action (RFC 5230). The evaluator computes ReplyTo (the envelope sender, falling back to the From header); the Executor is responsible for de-duplication and for actually sending the auto-reply.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL