func DirectionString(s string) (bidi.Direction, error) {
	t := Transformer{}
	if n, ok := t.advanceString(s); ok && n == len(s) {
		switch t.state {
		case ruleLTRFinal, ruleInitial:
			return bidi.LeftToRight, nil
		case ruleRTLFinal:
			return bidi.RightToLeft, nil
		}
	}
	return bidi.Neutral, ErrInvalid
}
DirectionString reports the direction of the given label as defined by RFC
5893 or an error if s is not a valid label according to the Bidi Rule.
package bidirule
import (
	"errors"
	"unicode/utf8"
	"golang.org/x/text/transform"
	"golang.org/x/text/unicode/bidi"
)
var ErrInvalid = errors.New("bidirule: failed Bidi Rule")
type ruleState uint8
const (
	ruleInitial ruleState = iota
	ruleLTR
	ruleLTRFinal
	ruleRTL
	ruleRTLFinal
	ruleInvalid
)
type ruleTransition struct {
	next ruleState
	mask uint16
}
var transitions = [...][2]ruleTransition{
	ruleInitial: {
		{ruleLTRFinal, 1 << bidi.L},
		{ruleRTLFinal, 1<<bidi.R | 1<<bidi.AL},
	},
	ruleRTL: {
		{ruleRTLFinal, 1<<bidi.R | 1<<bidi.AL | 1<<bidi.EN | 1<<bidi.AN},
		{ruleRTL, 1<<bidi.ES | 1<<bidi.CS | 1<<bidi.ET | 1<<bidi.ON | 1<<bidi.BN | 1<<bidi.NSM},
	},
	ruleRTLFinal: {
		{ruleRTLFinal, 1<<bidi.R | 1<<bidi.AL | 1<<bidi.EN | 1<<bidi.AN | 1<<bidi.NSM},
		{ruleRTL, 1<<bidi.ES | 1<<bidi.CS | 1<<bidi.ET | 1<<bidi.ON | 1<<bidi.BN},
	},
	ruleLTR: {
		{ruleLTRFinal, 1<<bidi.L | 1<<bidi.EN},
		{ruleLTR, 1<<bidi.ES | 1<<bidi.CS | 1<<bidi.ET | 1<<bidi.ON | 1<<bidi.BN | 1<<bidi.NSM},
	},
	ruleLTRFinal: {
		{ruleLTRFinal, 1<<bidi.L | 1<<bidi.EN | 1<<bidi.NSM},
		{ruleLTR, 1<<bidi.ES | 1<<bidi.CS | 1<<bidi.ET | 1<<bidi.ON | 1<<bidi.BN},
	},
	ruleInvalid: {
		{ruleInvalid, 0},
		{ruleInvalid, 0},
	},
}
const exclusiveRTL = uint16(1<<bidi.EN | 1<<bidi.AN)
func Direction(b []byte) (bidi.Direction, error) {
	t := Transformer{}
	if n, ok := t.advance(b); ok && n == len(b) {
		switch t.state {
		case ruleLTRFinal, ruleInitial:
			return bidi.LeftToRight, nil
		case ruleRTLFinal:
			return bidi.RightToLeft, nil
		}
	}
	return bidi.Neutral, ErrInvalid
}