From 88ab1a6d065d76109ff179561db6ce5acf728985 Mon Sep 17 00:00:00 2001
From: Pavel Antonov <antonov@perx.ru>
Date: Tue, 30 Jan 2024 17:43:21 +0400
Subject: [PATCH] WIP

---
 id/collection.go  | 34 +++++++++++++++++-----------------
 id/environment.go | 37 ++++++++++++++++++++-----------------
 id/id.go          | 21 ++++++++++++++++++++-
 id/json.go        |  2 +-
 id/space.go       | 21 +++++++++------------
 5 files changed, 67 insertions(+), 48 deletions(-)

diff --git a/id/collection.go b/id/collection.go
index 18e1008b..50bf64ee 100644
--- a/id/collection.go
+++ b/id/collection.go
@@ -13,7 +13,7 @@ type CollectionID struct {
 func (t *CollectionID) Type() string { return Collection }
 
 func (t *CollectionID) String() string {
-	return Join(t.EnvironmentID.String(), t.CollectionID)
+	return Join(t.EnvironmentID.String(), CollectionsPrefix, t.CollectionID)
 }
 
 func (t *CollectionID) ToMap() map[string]any {
@@ -30,22 +30,6 @@ func (t *CollectionID) FromMap(m map[string]any) error {
 	return nil
 }
 
-func (t *CollectionID) FromString(id string) error {
-	parts := Split(id)
-	return t.fromParts(parts)
-}
-
-func (t *CollectionID) fromParts(parts []string) error {
-	if err := t.EnvironmentID.fromParts(parts); err != nil {
-		return err
-	}
-	if len(parts) < 6 || parts[4] != CollectionsPrefix {
-		return ErrInvalidID
-	}
-	t.CollectionID = parts[5]
-	return nil
-}
-
 func (t *CollectionID) Validate() error {
 	if t.CollectionID == "" {
 		return ErrInvalidID
@@ -53,3 +37,19 @@ func (t *CollectionID) Validate() error {
 
 	return t.EnvironmentID.Validate()
 }
+
+func parseCollectionID(parts []string) (*CollectionID, error) {
+	if len(parts) != 6 || parts[0] != EnvironmentsPrefix {
+		return nil, ErrInvalidID
+	}
+
+	envID, err := parseEnvironmentID(parts[:4])
+	if err != nil {
+		return nil, err
+	}
+
+	var id CollectionID
+	id.CollectionID = parts[5]
+	id.EnvironmentID = *envID
+	return &id, nil
+}
diff --git a/id/environment.go b/id/environment.go
index f5ceab37..4958a33f 100644
--- a/id/environment.go
+++ b/id/environment.go
@@ -13,7 +13,10 @@ type EnvironmentID struct {
 func (t *EnvironmentID) Type() string { return Environment }
 
 func (t *EnvironmentID) String() string {
-	return Join(t.SpaceID.String(), t.EnvironmentID)
+	return Join(t.SpaceID.String(),
+		EnvironmentsPrefix, t.EnvironmentID,
+	)
+
 }
 
 func (t *EnvironmentID) ToMap() map[string]any {
@@ -30,22 +33,6 @@ func (t *EnvironmentID) FromMap(m map[string]any) error {
 	return nil
 }
 
-func (t *EnvironmentID) FromString(id string) error {
-	parts := Split(id)
-	return t.fromParts(parts)
-}
-
-func (t *EnvironmentID) fromParts(parts []string) error {
-	if err := t.SpaceID.fromParts(parts); err != nil {
-		return err
-	}
-	if len(parts) < 4 || parts[2] != EnvironmentsPrefix {
-		return ErrInvalidID
-	}
-	t.EnvironmentID = parts[3]
-	return nil
-}
-
 func (t *EnvironmentID) Validate() error {
 	if t.EnvironmentID == "" {
 		return ErrInvalidID
@@ -53,3 +40,19 @@ func (t *EnvironmentID) Validate() error {
 
 	return t.SpaceID.Validate()
 }
+
+func parseEnvironmentID(parts []string) (*EnvironmentID, error) {
+	if len(parts) != 4 || parts[2] != EnvironmentsPrefix {
+		return nil, ErrInvalidID
+	}
+
+	spaceID, err := parseSpaceID(parts[:2])
+	if err != nil {
+		return nil, err
+	}
+
+	var id EnvironmentID
+	id.EnvironmentID = parts[3]
+	id.SpaceID = *spaceID
+	return &id, nil
+}
diff --git a/id/id.go b/id/id.go
index 8f9ee6b8..a4ff8a5e 100644
--- a/id/id.go
+++ b/id/id.go
@@ -13,11 +13,30 @@ type ID interface {
 	String() string
 	Type() string
 	ToMap() map[string]any
-	FromString(string) error
 	FromMap(map[string]any) error
 	Validate() error
 }
 
+func Parse(s string) (ID, error) {
+	parts := Split(s)
+
+	// TODO: Парсим строку, от коротких к длинным
+
+	if id, err := parseSpaceID(parts); err != nil {
+		return id, nil
+	}
+
+	if id, _ := parseEnvironmentID(parts); id != nil {
+		return id, nil
+	}
+
+	if id, _ := parseCollectionID(parts); id != nil {
+		return id, nil
+	}
+
+	return nil, ErrInvalidID
+}
+
 func Split(id string) []string {
 	if id[0] != Separator {
 		return nil
diff --git a/id/json.go b/id/json.go
index ec510485..04fa39fa 100644
--- a/id/json.go
+++ b/id/json.go
@@ -1,3 +1,3 @@
 package id
 
-// Сохранение/чтение в JSON (в строку)
+// TODO: Сохранение/чтение в JSON (в строку)
diff --git a/id/space.go b/id/space.go
index 465412db..3d9d6c35 100644
--- a/id/space.go
+++ b/id/space.go
@@ -26,22 +26,19 @@ func (t *SpaceID) FromMap(m map[string]any) error {
 	return nil
 }
 
-func (t *SpaceID) FromString(id string) error {
-	parts := Split(id)
-	return t.fromParts(parts)
-}
-
-func (t *SpaceID) fromParts(parts []string) error {
-	if len(parts) < 2 || parts[0] != SpacesPrefix {
+func (t *SpaceID) Validate() error {
+	if t.SpaceID == "" {
 		return ErrInvalidID
 	}
-	t.SpaceID = parts[1]
 	return nil
 }
 
-func (t *SpaceID) Validate() error {
-	if t.SpaceID == "" {
-		return ErrInvalidID
+func parseSpaceID(parts []string) (*SpaceID, error) {
+	var id SpaceID
+	if len(parts) != 2 || parts[0] != SpacesPrefix {
+		return nil, ErrInvalidID
 	}
-	return nil
+
+	id.SpaceID = parts[1]
+	return &id, nil
 }
-- 
GitLab