Spaces:
Sleeping
Sleeping
| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: [email protected] | |
| // | |
| package crossref | |
| import ( | |
| "fmt" | |
| "net/url" | |
| "strings" | |
| "github.com/go-openapi/strfmt" | |
| "github.com/weaviate/weaviate/entities/models" | |
| ) | |
| const ( | |
| _LocalHost = "localhost" | |
| _Schema = "weaviate" | |
| ) | |
| // Ref is an abstraction of the cross-refs which are specified in a URI format | |
| // in the API. When this type is used it is safe to assume that a Ref is | |
| // semantically valid. This guarantee would not be possible on the URI format, | |
| // as the URI can be well-formed, but not contain the data we expect in it. | |
| // Do not use directly, such as crossref.Ref{}, as you won't have any | |
| // guarantees in this case. Always use one of the parsing options or New() | |
| type Ref struct { | |
| Local bool `json:"local"` | |
| PeerName string `json:"peerName"` | |
| TargetID strfmt.UUID `json:"targetID"` | |
| Class string `json:"className"` | |
| } | |
| // Parse is a safe way to generate a Ref, as it will error if any of the input | |
| // parameters are not as expected. | |
| func Parse(uriString string) (*Ref, error) { | |
| uri, err := url.Parse(uriString) | |
| if err != nil || uri.Path == "" { | |
| return nil, fmt.Errorf("invalid cref URI: %s", err) | |
| } | |
| segments := strings.Split(uri.Path, "/") | |
| class, id, idx := "", "", 1 | |
| switch len(segments) { | |
| case 3: | |
| class = segments[1] | |
| id = segments[2] | |
| idx = 2 | |
| case 2: | |
| id = segments[1] | |
| default: | |
| return nil, fmt.Errorf( | |
| "invalid cref URI: path must be of format '<class>/<uuid>', but got '%s'", uri.Path) | |
| } | |
| if ok := strfmt.IsUUID(id); !ok { | |
| return nil, fmt.Errorf("invalid cref URI: %dnd path segment must be uuid, but got '%s'", | |
| idx, id) | |
| } | |
| return &Ref{ | |
| Local: uri.Host == _LocalHost, | |
| PeerName: uri.Host, | |
| TargetID: strfmt.UUID(id), | |
| Class: class, | |
| }, nil | |
| } | |
| // ParseSingleRef is a safe way to generate a Ref from a models.SingleRef, a | |
| // helper construct that represents the API structure. It will error if any of | |
| // the input parameters are not as expected. | |
| func ParseSingleRef(singleRef *models.SingleRef) (*Ref, error) { | |
| return Parse(string(singleRef.Beacon)) | |
| } | |
| // New is a safe way to generate a Reference, as all required arguments must be | |
| // set in the constructor fn | |
| func New(peerName string, class string, target strfmt.UUID) *Ref { | |
| return &Ref{ | |
| Local: peerName == _LocalHost, | |
| PeerName: peerName, | |
| TargetID: target, | |
| Class: class, | |
| } | |
| } | |
| func NewLocalhost(class string, target strfmt.UUID) *Ref { | |
| return New(_LocalHost, class, target) | |
| } | |
| func (r *Ref) String() string { | |
| path := fmt.Sprintf("%s/%s", r.Class, r.TargetID) | |
| if r.Class == "" { | |
| path = fmt.Sprintf("/%s", r.TargetID) | |
| } | |
| uri := url.URL{ | |
| Host: r.PeerName, | |
| Scheme: _Schema, | |
| Path: path, | |
| } | |
| return uri.String() | |
| } | |
| // SingleRef converts the parsed Ref back into the API helper construct | |
| // containing a stringified representation (URI format) of the Ref | |
| func (r *Ref) SingleRef() *models.SingleRef { | |
| return &models.SingleRef{ | |
| Beacon: strfmt.URI(r.String()), | |
| } | |
| } | |