devicepath/parser.go

71 lines
1.8 KiB
Go

package devicepath
import (
"errors"
"fmt"
"strings"
)
var (
ErrUnknownSubType = errors.New("unknown device sub-type")
ErrMalformedString = errors.New("malformed device string")
)
type ErrInvalidArguments struct {
subErr error
}
func (e *ErrInvalidArguments) Error() string {
return fmt.Sprintf("invalid argument: %s", e.subErr.Error())
}
type ErrInvalidPath struct {
subErr error
node string
}
func (e *ErrInvalidPath) Error() string {
return fmt.Sprintf("invalid device path on section %q: %s", e.node, e.subErr.Error())
}
type nodeGenerator func() DevicePathNode
var prefixTypeAssociation = map[string]nodeGenerator{
sataPrefix: func() DevicePathNode { return &SataDevicePath{} },
pciPrefix: func() DevicePathNode { return &PCIDevicePath{} },
pciRootPrefix: func() DevicePathNode { return &PCIRootDevicePath{} },
hdPrefix: func() DevicePathNode { return &HardDriveDevicePath{} },
filePrefix: func() DevicePathNode { return &FileDevicePath{} },
macPrefix: func() DevicePathNode { return &MacDevicePath{} },
ipv4Prefix: func() DevicePathNode { return &Ipv4DevicePath{} },
ipv6Prefix: func() DevicePathNode { return &Ipv6DevicePath{} },
}
func Parsenode(raw string) (DevicePathNode, error) {
prefix := getPrefix(raw)
devGen, ok := prefixTypeAssociation[prefix]
if !ok {
return nil, ErrUnknownSubType
}
dev := devGen()
if err := dev.ParseString(raw); err != nil {
return nil, &ErrInvalidArguments{subErr: err}
}
return dev, nil
}
func ParseDevicePath(raw string) (*DevicePath, error) {
dp := DevicePath{}
for _, nodeStr := range strings.Split(raw, "/") {
node, err := Parsenode(nodeStr)
if err != nil {
return nil, &ErrInvalidPath{subErr: err, node: nodeStr}
}
if err := dp.PushNode(node); err != nil {
return nil, err
}
}
dp.PushNode(&FinalDevicePath{})
return &dp, nil
}