diff --git a/Unity/AmpAv.cs b/amp.Unity/AmpAv.cs
similarity index 100%
rename from Unity/AmpAv.cs
rename to amp.Unity/AmpAv.cs
diff --git a/Unity/AmpCore.cs b/amp.Unity/AmpCore.cs
similarity index 99%
rename from Unity/AmpCore.cs
rename to amp.Unity/AmpCore.cs
index 86c114d..5ae715c 100644
--- a/Unity/AmpCore.cs
+++ b/amp.Unity/AmpCore.cs
@@ -99,7 +99,7 @@ static AmpCoreReflection() {
"ChJFcnJDb2RlX0ludmFsaWRUYWcQj8z+////////ARIhChRFcnJDb2RlX0F0",
"dHJOb3RGb3VuZBCOzP7///////8BEiQKF0VyckNvZGVfTm90aGluZ1RvQ29t",
"bWl0EI3M/v///////wESIQoURXJyQ29kZV9Db21taXRGYWlsZWQQjMz+////",
- "////ARIiChVFcnJDb2RlX1NwYWNlTm90Rm91bmQQi8z+////////ARIjChZF",
+ "////ARIiChVFcnJDb2RlX1N0b3JlTm90Rm91bmQQi8z+////////ARIjChZF",
"cnJDb2RlX1N0b3JhZ2VGYWlsdXJlEIrM/v///////wESIAoTRXJyQ29kZV9B",
"cHBOb3RGb3VuZBCJzP7///////8BEiAKE0VyckNvZGVfTWFsZm9ybWVkVHgQ",
"iMz+////////ARIeChFFcnJDb2RlX0JhZFNjaGVtYRCAzP7///////8BEiAK",
@@ -191,7 +191,9 @@ public enum TxOpCode {
}
///
- /// TxBody contains a max number of uint64 fields usable for any purpose.
+ /// TxField maps a fixed count of int64 payload fields.enum
+ ///
+ /// Why not as a proto message? Because compression is much better since values mostly repeat.
///
public enum TxField {
[pbr::OriginalName("TxField_Nil")] Nil = 0,
@@ -344,7 +346,7 @@ public enum ErrCode {
[pbr::OriginalName("ErrCode_AttrNotFound")] AttrNotFound = -23026,
[pbr::OriginalName("ErrCode_NothingToCommit")] NothingToCommit = -23027,
[pbr::OriginalName("ErrCode_CommitFailed")] CommitFailed = -23028,
- [pbr::OriginalName("ErrCode_SpaceNotFound")] SpaceNotFound = -23029,
+ [pbr::OriginalName("ErrCode_StoreNotFound")] StoreNotFound = -23029,
[pbr::OriginalName("ErrCode_StorageFailure")] StorageFailure = -23030,
[pbr::OriginalName("ErrCode_AppNotFound")] AppNotFound = -23031,
[pbr::OriginalName("ErrCode_MalformedTx")] MalformedTx = -23032,
@@ -2834,7 +2836,7 @@ public string UID {
public const int TextFieldNumber = 13;
private string text_ = "";
///
- /// tag.Spec, custom content, or expression
+ /// tag.Expr, custom content, or expression
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
diff --git a/Unity/AmpCrates.cs b/amp.Unity/AmpCrates.cs
similarity index 100%
rename from Unity/AmpCrates.cs
rename to amp.Unity/AmpCrates.cs
diff --git a/Unity/AmpSki.cs b/amp.Unity/AmpSki.cs
similarity index 98%
rename from Unity/AmpSki.cs
rename to amp.Unity/AmpSki.cs
index b074089..7e5b400 100644
--- a/Unity/AmpSki.cs
+++ b/amp.Unity/AmpSki.cs
@@ -29,8 +29,8 @@ static AmpSkiReflection() {
"ASgOMhAuc2tpLkNyeXB0b0tpdElEEg0KBUJ1ZkluGAMgASgMEhoKBU9wS2V5",
"GAQgASgLMgsuc2tpLktleVJlZhIPCgdQZWVyS2V5GAUgASgMEhwKBlRvbWVJ",
"bhgGIAEoCzIMLnNraS5LZXlUb21lIi4KCkNyeXB0T3BPdXQSDgoGQnVmT3V0",
- "GAEgASgMEhAKCE9wUHViS2V5GAIgASgMInQKB0tleUluZm8SHQoHS2V5VHlw",
- "ZRgBIAEoDjIMLnNraS5LZXlUeXBlEiUKC0NyeXB0b0tpdElEGAIgASgOMhAu",
+ "GAEgASgMEhAKCE9wUHViS2V5GAIgASgMInQKB0tleUluZm8SHQoHS2V5Rm9y",
+ "bRgBIAEoDjIMLnNraS5LZXlGb3JtEiUKC0NyeXB0b0tpdElEGAIgASgOMhAu",
"c2tpLkNyeXB0b0tpdElEEhMKC1RpbWVDcmVhdGVkGAMgASgDEg4KBlB1Yktl",
"eRgEIAEoDCItCgZLZXlSZWYSEwoLS2V5cmluZ05hbWUYASABKAwSDgoGUHVi",
"S2V5GAIgASgMIjoKCEtleUVudHJ5Eh0KB0tleUluZm8YASABKAsyDC5za2ku",
@@ -44,9 +44,9 @@ static AmpSkiReflection() {
"RBIQCghIZWFkZXJTehgHIAEoDRITCgtIZWFkZXJDb2RlYxgIIAEoDRIOCgZC",
"b2R5U3oYCSABKAQiWAoMS2V5VG9tZUNyeXB0EgwKBFRvbWUYASABKAwSGwoG",
"S2V5UmVmGAogASgLMgsuc2tpLktleVJlZhIdCgdLZXlJbmZvGAsgASgLMgwu",
- "c2tpLktleUluZm8qbwoHS2V5VHlwZRIXChNLZXlUeXBlX1Vuc3BlY2lmaWVk",
- "EAASGAoUS2V5VHlwZV9TeW1tZXRyaWNLZXkQARIZChVLZXlUeXBlX0FzeW1t",
- "ZXRyaWNLZXkQAhIWChJLZXlUeXBlX1NpZ25pbmdLZXkQAypfCgtDcnlwdG9L",
+ "c2tpLktleUluZm8qbwoHS2V5Rm9ybRIXChNLZXlGb3JtX1Vuc3BlY2lmaWVk",
+ "EAASGAoUS2V5Rm9ybV9TeW1tZXRyaWNLZXkQARIZChVLZXlGb3JtX0FzeW1t",
+ "ZXRyaWNLZXkQAhIWChJLZXlGb3JtX1NpZ25pbmdLZXkQAypfCgtDcnlwdG9L",
"aXRJRBIhCh1DcnlwdG9LaXRJRF9VbnNwZWNpZmllZENyeXB0bxAAEhQKEENy",
"eXB0b0tpdElEX05hQ2wQARIXChNDcnlwdG9LaXRJRF9FRDI1NTE5EAIq0wEK",
"CUhhc2hLaXRJRBIgChxIYXNoS2l0SURfVW5zcGVjaWZpZWRIYXNoS2l0EAAS",
@@ -62,10 +62,10 @@ static AmpSkiReflection() {
"EAhiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Ski.KeyType), typeof(global::Ski.CryptoKitID), typeof(global::Ski.HashKitID), typeof(global::Ski.CryptOp), }, null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Ski.KeyForm), typeof(global::Ski.CryptoKitID), typeof(global::Ski.HashKitID), typeof(global::Ski.CryptOp), }, null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Ski.CryptOpArgs), global::Ski.CryptOpArgs.Parser, new[]{ "CryptOp", "DefaultCryptoKit", "BufIn", "OpKey", "PeerKey", "TomeIn" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Ski.CryptOpOut), global::Ski.CryptOpOut.Parser, new[]{ "BufOut", "OpPubKey" }, null, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Ski.KeyInfo), global::Ski.KeyInfo.Parser, new[]{ "KeyType", "CryptoKitID", "TimeCreated", "PubKey" }, null, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Ski.KeyInfo), global::Ski.KeyInfo.Parser, new[]{ "KeyForm", "CryptoKitID", "TimeCreated", "PubKey" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Ski.KeyRef), global::Ski.KeyRef.Parser, new[]{ "KeyringName", "PubKey" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Ski.KeyEntry), global::Ski.KeyEntry.Parser, new[]{ "KeyInfo", "PrivKey" }, null, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Ski.Keyring), global::Ski.Keyring.Parser, new[]{ "Name", "Keys", "SortedByPubKey", "NewestPubKey" }, null, null, null, null),
@@ -79,13 +79,13 @@ static AmpSkiReflection() {
}
#region Enums
///
- /// KeyType identifies how a key operates
+ /// KeyForm identifies how a key operates
///
- public enum KeyType {
- [pbr::OriginalName("KeyType_Unspecified")] Unspecified = 0,
- [pbr::OriginalName("KeyType_SymmetricKey")] SymmetricKey = 1,
- [pbr::OriginalName("KeyType_AsymmetricKey")] AsymmetricKey = 2,
- [pbr::OriginalName("KeyType_SigningKey")] SigningKey = 3,
+ public enum KeyForm {
+ [pbr::OriginalName("KeyForm_Unspecified")] Unspecified = 0,
+ [pbr::OriginalName("KeyForm_SymmetricKey")] SymmetricKey = 1,
+ [pbr::OriginalName("KeyForm_AsymmetricKey")] AsymmetricKey = 2,
+ [pbr::OriginalName("KeyForm_SigningKey")] SigningKey = 3,
}
///
@@ -821,7 +821,7 @@ public void MergeFrom(pb::CodedInputStream input) {
/// KeyInfo exists in two modes/uses:
/// 1) Generated/copied from an existing KeyEntry
/// 2) Key gen mode: used as a guide to generate a new key
- /// a) Fields used: KeyType and CryptoKitID (other fields ignored)
+ /// a) Fields used: KeyForm and CryptoKitID (other fields ignored)
///
public sealed partial class KeyInfo : pb::IMessage
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
@@ -857,7 +857,7 @@ public KeyInfo() {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public KeyInfo(KeyInfo other) : this() {
- keyType_ = other.keyType_;
+ keyForm_ = other.keyForm_;
cryptoKitID_ = other.cryptoKitID_;
timeCreated_ = other.timeCreated_;
pubKey_ = other.pubKey_;
@@ -870,18 +870,18 @@ public KeyInfo Clone() {
return new KeyInfo(this);
}
- /// Field number for the "KeyType" field.
- public const int KeyTypeFieldNumber = 1;
- private global::Ski.KeyType keyType_ = global::Ski.KeyType.Unspecified;
+ /// Field number for the "KeyForm" field.
+ public const int KeyFormFieldNumber = 1;
+ private global::Ski.KeyForm keyForm_ = global::Ski.KeyForm.Unspecified;
///
/// Specifies the type of key this is (optional)
///
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
- public global::Ski.KeyType KeyType {
- get { return keyType_; }
+ public global::Ski.KeyForm KeyForm {
+ get { return keyForm_; }
set {
- keyType_ = value;
+ keyForm_ = value;
}
}
@@ -945,7 +945,7 @@ public bool Equals(KeyInfo other) {
if (ReferenceEquals(other, this)) {
return true;
}
- if (KeyType != other.KeyType) return false;
+ if (KeyForm != other.KeyForm) return false;
if (CryptoKitID != other.CryptoKitID) return false;
if (TimeCreated != other.TimeCreated) return false;
if (PubKey != other.PubKey) return false;
@@ -956,7 +956,7 @@ public bool Equals(KeyInfo other) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public override int GetHashCode() {
int hash = 1;
- if (KeyType != global::Ski.KeyType.Unspecified) hash ^= KeyType.GetHashCode();
+ if (KeyForm != global::Ski.KeyForm.Unspecified) hash ^= KeyForm.GetHashCode();
if (CryptoKitID != global::Ski.CryptoKitID.UnspecifiedCrypto) hash ^= CryptoKitID.GetHashCode();
if (TimeCreated != 0L) hash ^= TimeCreated.GetHashCode();
if (PubKey.Length != 0) hash ^= PubKey.GetHashCode();
@@ -978,9 +978,9 @@ public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
- if (KeyType != global::Ski.KeyType.Unspecified) {
+ if (KeyForm != global::Ski.KeyForm.Unspecified) {
output.WriteRawTag(8);
- output.WriteEnum((int) KeyType);
+ output.WriteEnum((int) KeyForm);
}
if (CryptoKitID != global::Ski.CryptoKitID.UnspecifiedCrypto) {
output.WriteRawTag(16);
@@ -1004,9 +1004,9 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
- if (KeyType != global::Ski.KeyType.Unspecified) {
+ if (KeyForm != global::Ski.KeyForm.Unspecified) {
output.WriteRawTag(8);
- output.WriteEnum((int) KeyType);
+ output.WriteEnum((int) KeyForm);
}
if (CryptoKitID != global::Ski.CryptoKitID.UnspecifiedCrypto) {
output.WriteRawTag(16);
@@ -1030,8 +1030,8 @@ public void WriteTo(pb::CodedOutputStream output) {
[global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
public int CalculateSize() {
int size = 0;
- if (KeyType != global::Ski.KeyType.Unspecified) {
- size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) KeyType);
+ if (KeyForm != global::Ski.KeyForm.Unspecified) {
+ size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) KeyForm);
}
if (CryptoKitID != global::Ski.CryptoKitID.UnspecifiedCrypto) {
size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) CryptoKitID);
@@ -1054,8 +1054,8 @@ public void MergeFrom(KeyInfo other) {
if (other == null) {
return;
}
- if (other.KeyType != global::Ski.KeyType.Unspecified) {
- KeyType = other.KeyType;
+ if (other.KeyForm != global::Ski.KeyForm.Unspecified) {
+ KeyForm = other.KeyForm;
}
if (other.CryptoKitID != global::Ski.CryptoKitID.UnspecifiedCrypto) {
CryptoKitID = other.CryptoKitID;
@@ -1082,7 +1082,7 @@ public void MergeFrom(pb::CodedInputStream input) {
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 8: {
- KeyType = (global::Ski.KeyType) input.ReadEnum();
+ KeyForm = (global::Ski.KeyForm) input.ReadEnum();
break;
}
case 16: {
@@ -1113,7 +1113,7 @@ public void MergeFrom(pb::CodedInputStream input) {
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 8: {
- KeyType = (global::Ski.KeyType) input.ReadEnum();
+ KeyForm = (global::Ski.KeyForm) input.ReadEnum();
break;
}
case 16: {
@@ -1376,7 +1376,7 @@ public void MergeFrom(pb::CodedInputStream input) {
/// - KeyEntry.PrivKey == nil
/// - Fields used: KeyInfo.PubKey (other fields ignored)
/// 3) GenerateKeys "guide" mode: KeyInfo used as a guide to generate a new key
- /// - Fields used: KeyInfo.KeyType and KeyInfo.CryptoKitID (other fields ignored)
+ /// - Fields used: KeyInfo.KeyForm and KeyInfo.CryptoKitID (other fields ignored)
///
public sealed partial class KeyEntry : pb::IMessage
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
diff --git a/Unity/AmpStd.cs b/amp.Unity/AmpStd.cs
similarity index 100%
rename from Unity/AmpStd.cs
rename to amp.Unity/AmpStd.cs
diff --git a/Unity/AmpStdEx.cs b/amp.Unity/AmpStdEx.cs
similarity index 55%
rename from Unity/AmpStdEx.cs
rename to amp.Unity/AmpStdEx.cs
index f788769..561880e 100644
--- a/Unity/AmpStdEx.cs
+++ b/amp.Unity/AmpStdEx.cs
@@ -6,33 +6,33 @@ namespace Amp.Std {
public static partial class Spec {
public static readonly TagID MetaNodeID = new(0, 0, 2701);
- public static readonly TagSpec TagRoot = new TagSpec().With("amp");
- public static readonly TagSpec AttrSpec = TagRoot.With("attr");
- public static readonly TagSpec AppSpec = TagRoot.With("app");
- public static readonly TagSpec CellChildren = AttrSpec.With("children.TagID");
- public static readonly TagSpec CellProperties = AttrSpec.With("cell-properties");
+ public static readonly TagExpr TagRoot = new TagExpr().With("amp");
+ public static readonly TagExpr AttrSpec = TagRoot.With("attr");
+ public static readonly TagExpr AppSpec = TagRoot.With("app");
+ public static readonly TagExpr CellChildren = AttrSpec.With("children.Tag.ID");
+ public static readonly TagExpr CellProperties = AttrSpec.With("cell-properties");
- public static readonly TagSpec Property = new TagSpec().With("cell-property");
+ public static readonly TagExpr Property = new TagExpr().With("cell-property");
- public static readonly TagSpec Glyphs = Property.With("Tags.glyphs");
- public static readonly TagSpec Links = Property.With("Tags.links");
+ public static readonly TagExpr Glyphs = Property.With("Tags.glyphs");
+ public static readonly TagExpr Links = Property.With("Tags.links");
public static readonly TagID CellMediaID = Property.With("Tag.content.media").ID;
public static readonly TagID CellCover = Property.With("Tag.content.cover").ID;
public static readonly TagID CellVis = Property.With("Tag.content.vis").ID;
- public static readonly TagSpec TextTag = Property.With("Tag.text");
+ public static readonly TagExpr TextTag = Property.With("Tag.text");
public static readonly TagID CellLabel = TextTag.With("label").ID;
public static readonly TagID CellCaption = TextTag.With("caption").ID;
public static readonly TagID CellCollection = TextTag.With("collection").ID;
// Meta attrs registered (allowed) to be pushed
- public static readonly TagSpec Login = Registry.RegisterPrototype();
- public static readonly TagSpec LoginChallenge = Registry.RegisterPrototype();
- public static readonly TagSpec LoginResponse = Registry.RegisterPrototype();
- public static readonly TagSpec LoginCheckpoint = Registry.RegisterPrototype();
- public static readonly TagSpec PinRequest = Registry.RegisterPrototype();
- public static readonly TagSpec LaunchURL = Registry.RegisterPrototype();
+ public static readonly TagExpr Login = Registry.RegisterPrototype();
+ public static readonly TagExpr LoginChallenge = Registry.RegisterPrototype();
+ public static readonly TagExpr LoginResponse = Registry.RegisterPrototype();
+ public static readonly TagExpr LoginCheckpoint = Registry.RegisterPrototype();
+ public static readonly TagExpr PinRequest = Registry.RegisterPrototype();
+ public static readonly TagExpr LaunchURL = Registry.RegisterPrototype();
public static readonly TagID Err = Registry.RegisterPrototype().ID;
public static readonly TagID Tag = Registry.RegisterPrototype().ID;
diff --git a/amp/amp.core.pb.go b/amp/amp.core.pb.go
index ab91ec5..4a7edfe 100644
--- a/amp/amp.core.pb.go
+++ b/amp/amp.core.pb.go
@@ -104,7 +104,9 @@ func (TxOpCode) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_ab24c3800b7c0c17, []int{1}
}
-// TxBody contains a max number of uint64 fields usable for any purpose.
+// TxField maps a fixed count of int64 payload fields.enum
+//
+// Why not as a proto message? Because compression is much better since values mostly repeat.
type TxField int32
const (
@@ -412,7 +414,7 @@ const (
ErrCode_AttrNotFound ErrCode = -23026
ErrCode_NothingToCommit ErrCode = -23027
ErrCode_CommitFailed ErrCode = -23028
- ErrCode_SpaceNotFound ErrCode = -23029
+ ErrCode_StoreNotFound ErrCode = -23029
ErrCode_StorageFailure ErrCode = -23030
ErrCode_AppNotFound ErrCode = -23031
ErrCode_MalformedTx ErrCode = -23032
@@ -461,7 +463,7 @@ var ErrCode_name = map[int32]string{
-23026: "ErrCode_AttrNotFound",
-23027: "ErrCode_NothingToCommit",
-23028: "ErrCode_CommitFailed",
- -23029: "ErrCode_SpaceNotFound",
+ -23029: "ErrCode_StoreNotFound",
-23030: "ErrCode_StorageFailure",
-23031: "ErrCode_AppNotFound",
-23032: "ErrCode_MalformedTx",
@@ -510,7 +512,7 @@ var ErrCode_value = map[string]int32{
"ErrCode_AttrNotFound": -23026,
"ErrCode_NothingToCommit": -23027,
"ErrCode_CommitFailed": -23028,
- "ErrCode_SpaceNotFound": -23029,
+ "ErrCode_StoreNotFound": -23029,
"ErrCode_StorageFailure": -23030,
"ErrCode_AppNotFound": -23031,
"ErrCode_MalformedTx": -23032,
@@ -1400,7 +1402,7 @@ func init() {
func init() { proto.RegisterFile("amp.core.proto", fileDescriptor_ab24c3800b7c0c17) }
var fileDescriptor_ab24c3800b7c0c17 = []byte{
- // 2143 bytes of a gzipped FileDescriptorProto
+ // 2142 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x58, 0xcb, 0x73, 0x1b, 0x49,
0x19, 0xf7, 0x48, 0xf2, 0x43, 0x6d, 0xc7, 0x6e, 0xf7, 0xc6, 0xc9, 0x6c, 0x88, 0x15, 0xa3, 0x64,
0xc1, 0xa8, 0x76, 0x93, 0x58, 0x61, 0x0f, 0x1c, 0x6d, 0x4b, 0x4e, 0x54, 0x7e, 0xd6, 0x48, 0x0e,
@@ -1506,35 +1508,35 @@ var fileDescriptor_ab24c3800b7c0c17 = []byte{
0x1d, 0x53, 0xd7, 0xb1, 0x0f, 0xad, 0x06, 0xfe, 0x5a, 0xa6, 0xab, 0x1b, 0xd4, 0xbe, 0x4d, 0xdd,
0x01, 0xe0, 0x37, 0xfe, 0xdf, 0xfa, 0x16, 0xed, 0xe2, 0xaf, 0x66, 0xdf, 0x10, 0x29, 0x45, 0x1c,
0xc8, 0x57, 0x32, 0xc3, 0xdd, 0xe3, 0xb2, 0xe7, 0xb0, 0x6e, 0x8b, 0x6f, 0xf2, 0x7e, 0xdf, 0x91,
- 0xf8, 0xcb, 0x99, 0x86, 0x02, 0x32, 0xcc, 0xfd, 0x97, 0x32, 0x33, 0xd2, 0xf4, 0x68, 0x1b, 0xe2,
- 0xcd, 0xbe, 0x98, 0x7d, 0x3e, 0x92, 0x0b, 0xda, 0x05, 0x65, 0x67, 0x20, 0x00, 0xbf, 0x9e, 0x79,
- 0xcc, 0xeb, 0x9e, 0x17, 0x9b, 0xf9, 0x42, 0xa6, 0x62, 0x97, 0xba, 0x1d, 0x2e, 0xfa, 0x60, 0xb7,
- 0x86, 0xf8, 0xf3, 0x89, 0xa2, 0x84, 0x16, 0x53, 0x89, 0xd3, 0xdd, 0x8c, 0xe2, 0xd7, 0x32, 0x2d,
- 0xa8, 0xf6, 0x18, 0x79, 0xf1, 0xf4, 0x41, 0x96, 0x85, 0xfa, 0x50, 0x95, 0x4d, 0x5d, 0x08, 0xfc,
- 0x41, 0x26, 0x7f, 0x10, 0x5f, 0xc5, 0xff, 0x3c, 0xc8, 0xcc, 0x18, 0xb8, 0x6e, 0x1c, 0xc6, 0xbf,
- 0x1f, 0x64, 0x39, 0x71, 0x20, 0xf8, 0xb1, 0x63, 0x83, 0x50, 0x9b, 0xfc, 0x2b, 0x51, 0x7c, 0x14,
- 0x5d, 0x88, 0x14, 0xb7, 0x1d, 0xee, 0x52, 0x09, 0xfe, 0xba, 0xe7, 0x01, 0xb3, 0xf7, 0x99, 0x3b,
- 0xc2, 0xff, 0x48, 0x84, 0x2f, 0xa2, 0x4b, 0xc9, 0x4d, 0xf0, 0x07, 0x9d, 0x8e, 0xd3, 0x76, 0x80,
- 0xc9, 0x03, 0x10, 0x7d, 0x47, 0xd7, 0x81, 0x8f, 0xff, 0x9e, 0xa8, 0xaf, 0xa1, 0x72, 0xec, 0x5b,
- 0xd4, 0x9b, 0xd6, 0x5d, 0xa1, 0x2a, 0xc1, 0x82, 0xae, 0xe3, 0x4b, 0x50, 0x25, 0xf3, 0xc7, 0x64,
- 0x41, 0x05, 0x2d, 0x27, 0x2d, 0x22, 0xf9, 0xfa, 0xc4, 0x8b, 0xf1, 0x1f, 0x1e, 0x64, 0xdd, 0x83,
- 0x1a, 0xb4, 0x95, 0x22, 0x4c, 0xce, 0xef, 0x33, 0xed, 0xdd, 0x06, 0xe1, 0x74, 0x46, 0xaa, 0x31,
- 0x52, 0x39, 0x10, 0x10, 0x6a, 0xdf, 0xcd, 0x4c, 0xe4, 0x06, 0xb5, 0xb7, 0x61, 0xb4, 0xc5, 0x45,
- 0x9f, 0x4a, 0xfc, 0xbb, 0x44, 0xb2, 0x8a, 0x3e, 0x14, 0x49, 0xb6, 0x61, 0x74, 0x13, 0x18, 0x08,
- 0xfd, 0xfc, 0x0c, 0x8d, 0xfd, 0xf6, 0x41, 0xd6, 0x6d, 0xdf, 0x86, 0x91, 0x70, 0x58, 0x37, 0x3e,
- 0x98, 0xdf, 0x24, 0xaa, 0x17, 0x90, 0x99, 0x52, 0xd5, 0x99, 0x14, 0xa3, 0x58, 0xf6, 0x4e, 0xa6,
- 0x31, 0xf5, 0xe3, 0x78, 0xdb, 0x49, 0x3a, 0xc5, 0xaf, 0x33, 0x55, 0x61, 0x4f, 0x8a, 0xbb, 0xce,
- 0xdb, 0x99, 0x21, 0x3c, 0x93, 0xe1, 0x7d, 0x0f, 0xff, 0x2a, 0x33, 0xbf, 0xbb, 0x54, 0xf8, 0x3d,
- 0xea, 0x86, 0x61, 0xfe, 0x32, 0x73, 0xcf, 0x43, 0xd6, 0x1f, 0x53, 0xfd, 0x22, 0x56, 0x55, 0x6a,
- 0x68, 0x26, 0xfa, 0x85, 0xa1, 0x5e, 0x07, 0xd1, 0xf8, 0xa8, 0x2e, 0x04, 0x17, 0x78, 0x42, 0x7d,
- 0x23, 0x63, 0xec, 0x93, 0x54, 0xa8, 0xf7, 0x4b, 0x1a, 0x6a, 0xb0, 0x0e, 0xc7, 0x85, 0x0d, 0x78,
- 0xf8, 0xa8, 0x34, 0xf1, 0xfe, 0xa3, 0xd2, 0xc4, 0x93, 0x47, 0x25, 0xe3, 0xb5, 0x93, 0x92, 0xf1,
- 0xd3, 0x93, 0x92, 0xf1, 0xde, 0x49, 0xc9, 0x78, 0x78, 0x52, 0x32, 0xfe, 0x7a, 0x52, 0x32, 0xfe,
- 0x76, 0x52, 0x9a, 0x78, 0x72, 0x52, 0x32, 0xde, 0x78, 0x5c, 0x9a, 0x78, 0xf8, 0xb8, 0x34, 0xf1,
- 0xfe, 0xe3, 0xd2, 0xc4, 0x9d, 0x8f, 0x75, 0x1d, 0xd9, 0x1b, 0xdc, 0xbd, 0xda, 0xe6, 0xfd, 0x6b,
- 0x54, 0xc8, 0x97, 0xfa, 0x60, 0x3b, 0xf4, 0x25, 0xcf, 0xa5, 0x52, 0x95, 0xf3, 0x35, 0xfd, 0x9b,
- 0xb9, 0xb6, 0xad, 0xfe, 0xff, 0x59, 0x2e, 0xbf, 0xde, 0xf7, 0xee, 0x4e, 0xe9, 0xbf, 0x91, 0xdd,
- 0xf8, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb1, 0xa7, 0xd1, 0xca, 0x35, 0x13, 0x00, 0x00,
+ 0xf8, 0xcb, 0x99, 0x86, 0x02, 0x32, 0xcc, 0xfd, 0x97, 0x32, 0x33, 0xd2, 0x94, 0x5c, 0x40, 0xbc,
+ 0xd9, 0x17, 0xb3, 0xcf, 0x47, 0x72, 0x41, 0xbb, 0xa0, 0xec, 0x0c, 0x04, 0xe0, 0xd7, 0x33, 0x8f,
+ 0x79, 0xdd, 0xf3, 0x62, 0x33, 0x5f, 0xc8, 0x54, 0xec, 0x52, 0xb7, 0xc3, 0x45, 0x1f, 0xec, 0xd6,
+ 0x10, 0x7f, 0x3e, 0x51, 0x94, 0xd0, 0x62, 0x2a, 0x71, 0xba, 0x9b, 0x51, 0xfc, 0x5a, 0xa6, 0x05,
+ 0xd5, 0x1e, 0x23, 0x2f, 0x9e, 0x3e, 0xc8, 0xb2, 0x50, 0x1f, 0xaa, 0xb2, 0xa9, 0x0b, 0x81, 0x3f,
+ 0xc8, 0xe4, 0x0f, 0xe2, 0xab, 0xf8, 0x9f, 0x07, 0x99, 0x19, 0x03, 0xd7, 0x8d, 0xc3, 0xf8, 0xf7,
+ 0x83, 0x2c, 0x27, 0x0e, 0x04, 0x3f, 0x76, 0x6c, 0x10, 0x6a, 0x93, 0x7f, 0x25, 0x8a, 0x8f, 0xa2,
+ 0x0b, 0x91, 0xe2, 0xb6, 0xc3, 0x5d, 0x2a, 0xc1, 0x5f, 0xf7, 0x3c, 0x60, 0xf6, 0x3e, 0x73, 0x47,
+ 0xf8, 0x1f, 0x89, 0xf0, 0x45, 0x74, 0x29, 0xb9, 0x09, 0xfe, 0xa0, 0xd3, 0x71, 0xda, 0x0e, 0x30,
+ 0x79, 0x00, 0xa2, 0xef, 0xe8, 0x3a, 0xf0, 0xf1, 0xdf, 0x13, 0xf5, 0x35, 0x54, 0x8e, 0x7d, 0x8b,
+ 0x7a, 0xd3, 0xba, 0x2b, 0x54, 0x25, 0x58, 0xd0, 0x75, 0x7c, 0x09, 0xaa, 0x64, 0xfe, 0x98, 0x2c,
+ 0xa8, 0xa0, 0xe5, 0xa4, 0x45, 0x24, 0x5f, 0x9f, 0x78, 0x31, 0xfe, 0xc3, 0x83, 0xac, 0x7b, 0x50,
+ 0x83, 0xb6, 0x52, 0x84, 0xc9, 0xf9, 0x7d, 0xa6, 0xbd, 0xdb, 0x20, 0x9c, 0xce, 0x48, 0x35, 0x46,
+ 0x2a, 0x07, 0x02, 0x42, 0xed, 0xbb, 0x99, 0x89, 0xdc, 0xa0, 0xf6, 0x36, 0x8c, 0xb6, 0xb8, 0xe8,
+ 0x53, 0x89, 0x7f, 0x97, 0x48, 0x56, 0xd1, 0x87, 0x22, 0xc9, 0x36, 0x8c, 0x6e, 0x02, 0x03, 0xa1,
+ 0x9f, 0x9f, 0xa1, 0xb1, 0xdf, 0x3e, 0xc8, 0xba, 0xed, 0xdb, 0x30, 0x12, 0x0e, 0xeb, 0xc6, 0x07,
+ 0xf3, 0x9b, 0x44, 0xf5, 0x02, 0x32, 0x53, 0xaa, 0x3a, 0x93, 0x62, 0x14, 0xcb, 0xde, 0xc9, 0x34,
+ 0xa6, 0x7e, 0x1c, 0x6f, 0x3b, 0x49, 0xa7, 0xf8, 0x75, 0xa6, 0x2a, 0xec, 0x49, 0x71, 0xd7, 0x79,
+ 0x3b, 0x33, 0x84, 0x67, 0x32, 0xbc, 0xef, 0xe1, 0x5f, 0x65, 0xe6, 0x77, 0x97, 0x0a, 0xbf, 0x47,
+ 0xdd, 0x30, 0xcc, 0x5f, 0x66, 0xee, 0x79, 0xc8, 0xfa, 0x63, 0xaa, 0x5f, 0xc4, 0xaa, 0x4a, 0x0d,
+ 0xcd, 0x44, 0xbf, 0x30, 0xd4, 0xeb, 0x20, 0x1a, 0x1f, 0xd5, 0x85, 0xe0, 0x02, 0x4f, 0xa8, 0x6f,
+ 0x64, 0x8c, 0x7d, 0x92, 0x0a, 0xf5, 0x7e, 0x49, 0x43, 0x0d, 0xd6, 0xe1, 0xb8, 0xb0, 0x01, 0x0f,
+ 0x1f, 0x95, 0x26, 0xde, 0x7f, 0x54, 0x9a, 0x78, 0xf2, 0xa8, 0x64, 0xbc, 0x76, 0x52, 0x32, 0x7e,
+ 0x7a, 0x52, 0x32, 0xde, 0x3b, 0x29, 0x19, 0x0f, 0x4f, 0x4a, 0xc6, 0x5f, 0x4f, 0x4a, 0xc6, 0xdf,
+ 0x4e, 0x4a, 0x13, 0x4f, 0x4e, 0x4a, 0xc6, 0x1b, 0x8f, 0x4b, 0x13, 0x0f, 0x1f, 0x97, 0x26, 0xde,
+ 0x7f, 0x5c, 0x9a, 0xb8, 0xf3, 0xb1, 0xae, 0x23, 0x7b, 0x83, 0xbb, 0x57, 0xdb, 0xbc, 0x7f, 0x8d,
+ 0x0a, 0xf9, 0x52, 0x1f, 0x6c, 0x87, 0xbe, 0xe4, 0xb9, 0x54, 0xaa, 0x72, 0xbe, 0xa6, 0x7f, 0x33,
+ 0xd7, 0xb6, 0xd5, 0xff, 0x3f, 0xcb, 0xe5, 0xd7, 0xfb, 0xde, 0xdd, 0x29, 0xfd, 0x37, 0xb2, 0x1b,
+ 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x8a, 0xf5, 0x15, 0x54, 0x35, 0x13, 0x00, 0x00,
}
func (x Const) String() string {
diff --git a/amp/amp.core.proto b/amp/amp.core.proto
index 6e9abd3..c80f43f 100644
--- a/amp/amp.core.proto
+++ b/amp/amp.core.proto
@@ -53,7 +53,9 @@ enum TxOpCode {
}
-// TxBody contains a max number of uint64 fields usable for any purpose.
+// TxField maps a fixed count of int64 payload fields.enum
+//
+// Why not as a proto message? Because compression is much better since values mostly repeat.
enum TxField {
TxField_Nil = 0;
@@ -251,7 +253,7 @@ message Tag {
string ContentType = 10; // e.g. "text/html", "image/png", "image/*", "amp.vis/content.*"
string UID = 12; // UID, SKU, or other literal
- string Text = 13; // tag.Spec, custom content, or expression
+ string Text = 13; // tag.Expr, custom content, or expression
string URL = 15; // IEEE 1738 URL: schema://hostname.com/path/query
// Metric specifies the metric system used for the size metric values
@@ -371,7 +373,7 @@ enum ErrCode {
ErrCode_AttrNotFound = -23026;
ErrCode_NothingToCommit = -23027;
ErrCode_CommitFailed = -23028;
- ErrCode_SpaceNotFound = -23029;
+ ErrCode_StoreNotFound = -23029;
ErrCode_StorageFailure = -23030;
ErrCode_AppNotFound = -23031;
ErrCode_MalformedTx = -23032;
diff --git a/amp/amp.registry.go b/amp/amp.registry.go
index 2ff39db..0aad9e2 100644
--- a/amp/amp.registry.go
+++ b/amp/amp.registry.go
@@ -26,7 +26,7 @@ type registry struct {
attrDefs map[tag.ID]AttrDef
}
-func (reg *registry) RegisterPrototype(context tag.Spec, prototype tag.Value, subTags string) tag.Spec {
+func (reg *registry) RegisterPrototype(context tag.Expr, prototype tag.Value, subTags string) tag.Expr {
if subTags == "" {
typeOf := reflect.TypeOf(prototype)
if typeOf.Kind() == reflect.Ptr {
@@ -35,14 +35,14 @@ func (reg *registry) RegisterPrototype(context tag.Spec, prototype tag.Value, su
subTags = typeOf.Name()
}
- attrSpec := context.With(subTags)
+ attrExpr := context.With(subTags)
reg.mu.Lock()
defer reg.mu.Unlock()
- reg.attrDefs[attrSpec.ID] = AttrDef{
- Spec: attrSpec,
+ reg.attrDefs[attrExpr.ID] = AttrDef{
+ Expr: attrExpr,
Prototype: prototype,
}
- return attrSpec
+ return attrExpr
}
func (reg *registry) Import(other Registry) error {
@@ -141,9 +141,9 @@ func (reg *registry) MakeValue(attrSpec tag.ID) (tag.Value, error) {
/*
func (reg *registry) RegisterDefs(defs *RegisterDefs) error {
- for _, tagSpec := range defs.TagSpecs {
+ for _, tagExpr := range defs.TagExprs {
def := AttrDef{
- Spec: tag.FormSpec(tag.Spec{}, tagSpec),
+ Spec: tag.FormSpec(tag.Expr{}, tagExpr),
}
reg.attrDefs[def.Spec.ID] = def
}
@@ -158,20 +158,20 @@ func MakeSchemaForType(valTyp reflect.Type) (*AttrSchema, error) {
schema := &AttrSchema{
CellDataModel: valTyp.Name(),
SchemaName: "on-demand-reflect",
- Attrs: make([]*tag.Spec, 0, numFields),
+ Attrs: make([]*tag.Expr, 0, numFields),
}
for i := 0; i < numFields; i++ {
- // Importantly, TagSpecID is always set to the field index + 1, so we know what field to inspect when given an TagSpecID.
+ // Importantly, TagExprID is always set to the field index + 1, so we know what field to inspect when given an TagExprID.
field := valTyp.Field(i)
if !field.IsExported() {
continue
}
- attr := &tag.Spec{
+ attr := &tag.Expr{
TypedName: field.Name,
- TagSpecID: int32(i + 1),
+ TagExprID: int32(i + 1),
}
attrType := field.Type
@@ -233,7 +233,7 @@ func ReadCell(ctx AppContext, subKey string, schema *AttrSchema, dstStruct any)
for _, ai := range schema.Attrs {
if ai.TypedName == field.Name {
for _, msg := range msgs {
- if msg.TagSpecID == ai.TagSpecID {
+ if msg.TagExprID == ai.TagExprID {
msg.LoadVal(dst.Field(fi).Addr().Interface())
goto nextField
}
@@ -271,7 +271,7 @@ func WriteCell(ctx AppContext, subKey string, schema *AttrSchema, srcStruct any)
for _, attr := range schema.Attrs {
msg := tx.AddMsg()
msg.Op = MsgOp_PushAttr
- msg.TagSpecID = attr.TagSpecID
+ msg.TagExprID = attr.TagExprID
for i := 0; i < numFields; i++ {
if valType.Field(i).Name == attr.TypedName {
msg.setVal(src.Field(i).Interface())
diff --git a/amp/amp.support.attrs.go b/amp/amp.support.attrs.go
index af500df..c882ba9 100644
--- a/amp/amp.support.attrs.go
+++ b/amp/amp.support.attrs.go
@@ -11,7 +11,7 @@ var (
// CellID hard-wired to denote the root c
MetaNodeID = tag.ID{0, 0, 2701}
- TagRoot = tag.Spec{}.With("amp")
+ TagRoot = tag.Expr{}.With("amp")
AttrSpec = TagRoot.With("attr")
AppSpec = TagRoot.With("app")
)
@@ -65,7 +65,7 @@ func (v *Tag) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *Tag) TagSpec() tag.Spec {
+func (v *Tag) TagExpr() tag.Expr {
return AttrSpec.With("Tag")
}
@@ -84,7 +84,7 @@ func (v *Tags) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *Tags) TagSpec() tag.Spec {
+func (v *Tags) TagExpr() tag.Expr {
return AttrSpec.With("Tags")
}
@@ -107,7 +107,7 @@ func (v *Tag) AsID() tag.ID {
if v.UID != "" {
v.SetID(tag.FromLiteral([]byte(v.UID)))
} else if v.Text != "" {
- v.SetID(tag.FromString(v.Text))
+ v.SetID(tag.FromExpr(v.Text))
}
}
return [3]uint64{
@@ -139,7 +139,7 @@ func (v *Err) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *Err) TagSpec() tag.Spec {
+func (v *Err) TagExpr() tag.Expr {
return AttrSpec.With("Err")
}
@@ -183,7 +183,7 @@ func (v *LaunchURL) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *LaunchURL) TagSpec() tag.Spec {
+func (v *LaunchURL) TagExpr() tag.Expr {
return AttrSpec.With("LaunchURL")
}
@@ -195,7 +195,7 @@ func (v *Login) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *Login) TagSpec() tag.Spec {
+func (v *Login) TagExpr() tag.Expr {
return AttrSpec.With("Login")
}
@@ -207,7 +207,7 @@ func (v *LoginChallenge) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *LoginChallenge) TagSpec() tag.Spec {
+func (v *LoginChallenge) TagExpr() tag.Expr {
return AttrSpec.With("LoginChallenge")
}
@@ -219,7 +219,7 @@ func (v *LoginResponse) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *LoginResponse) TagSpec() tag.Spec {
+func (v *LoginResponse) TagExpr() tag.Expr {
return AttrSpec.With("LoginResponse")
}
@@ -231,7 +231,7 @@ func (v *LoginCheckpoint) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *LoginCheckpoint) TagSpec() tag.Spec {
+func (v *LoginCheckpoint) TagExpr() tag.Expr {
return AttrSpec.With("LoginCheckpoint")
}
@@ -243,7 +243,7 @@ func (v *PinRequest) MarshalToStore(in []byte) (out []byte, err error) {
return MarshalPbToStore(v, in)
}
-func (v *PinRequest) TagSpec() tag.Spec {
+func (v *PinRequest) TagExpr() tag.Expr {
return AttrSpec.With("PinRequest")
}
@@ -265,7 +265,7 @@ func (v *Request) AttrsToPin() map[tag.ID]struct{} {
for _, attr := range v.PinAttrs {
attrID := attr.AttrID()
if attrID.IsNil() && attr.URL != "" {
- attrID = tag.FormSpec(tag.Spec{}, attr.URL).ID
+ attrID = tag.FormSpec(tag.Expr{}, attr.URL).ID
}
if !attrID.IsNil() {
pinAttrs[attrID] = struct{}{}
diff --git a/amp/amp.support.tx.go b/amp/amp.support.tx.go
index d9a145a..f30f4e2 100644
--- a/amp/amp.support.tx.go
+++ b/amp/amp.support.tx.go
@@ -90,9 +90,9 @@ func (tx *TxMsg) ReleaseRef() {
func MarshalAttr(cellID, attrID tag.ID, attrVal tag.Value) (*TxMsg, error) {
tx := NewTxMsg(true)
if attrID.IsNil() && attrVal != nil {
- attrID = attrVal.TagSpec().ID
+ attrID = attrVal.TagExpr().ID
if attrID.IsNil() {
- return nil, ErrCode_AssertFailed.Error("MarshalAttr: missing builtin tag.Spec")
+ return nil, ErrCode_AssertFailed.Error("MarshalAttr: missing builtin tag.Expr")
}
}
op := TxOp{}
@@ -199,7 +199,7 @@ func (tx *TxMsg) Upsert(cellID, attrID, itemID tag.ID, val tag.Value) error {
return tx.MarshalOp(&op, val)
}
-// Marshals a TxOp and optional value to the given Tx's to and data store.
+// Marshals a TxOp and optional value to the given Tx's data store.
//
// On success:
// - TxOp.DataOfs and TxOp.DataLen are overwritten,
diff --git a/amp/amp.support_test.go b/amp/amp.support_test.go
index f10ac64..466596c 100644
--- a/amp/amp.support_test.go
+++ b/amp/amp.support_test.go
@@ -115,7 +115,7 @@ func TestRegistry(t *testing.T) {
if spec.Canonic != AttrSpec.Canonic+".av.Hello.World.Tag" {
t.Fatal("RegisterPrototype failed")
}
- if spec.ID != (tag.Spec{}.With("amp.attr.World.Tag.Hello.av")).ID {
+ if spec.ID != (tag.Expr{}.With("amp.attr.World.Tag.Hello.av")).ID {
t.Fatalf("tag.FormSpec failed")
}
if spec.ID != AttrSpec.With("av").With("World.Hello.Tag").ID {
@@ -125,7 +125,7 @@ func TestRegistry(t *testing.T) {
t.Fatalf("unexpected spec.ID: %v", spec.ID)
}
if (tag.ID{}).Base32() != "0" {
- t.Fatalf("tag.Spec{}.Base32() failed")
+ t.Fatalf("tag.Expr{}.Base32() failed")
}
if spec.ID.Base32() != "3t1sm7v1ycu8rzmysqc2d93wsyg70m6cn" {
t.Errorf("tag.ID.Base32() failed: %v", spec.ID.Base32())
diff --git a/amp/api.app.go b/amp/api.app.go
index 8eba920..37a5c80 100644
--- a/amp/api.app.go
+++ b/amp/api.app.go
@@ -11,7 +11,7 @@ import (
//
// Similar to a traditional OS service, an amp.App responds to queries it recognizes and operates on client requests. The stock amp runtime offers essential apps, such as file system access and user account services.
type App struct {
- AppSpec tag.Spec // unique and persistent ID for this module
+ AppSpec tag.Expr // unique and persistent ID for this module
Desc string // human-readable description of this app
Version string // "v{MajorVers}.{MinorID}.{RevID}"
Dependencies []tag.ID // module Tags this app may access
@@ -33,7 +33,7 @@ type AppContext interface {
// This directory is scoped by App.AppSpec
LocalDataPath() string
- // Gets the named attribute from the user's home space -- used high-level app settings.
+ // Gets the named attribute from the user's home storage -- used high-level app settings.
// The attr is scoped by both the app Tag so key collision with other users or apps is not possible.
// This is how an app can store and retrieve its settings for the current user.
GetAppAttr(attrSpec tag.ID, dst tag.Value) error
@@ -89,7 +89,7 @@ type ElementID [3]tag.ID
// TxOpID is TxOp atomic edit entry ID, functioning as a multi-part LSM key: CellID / AttrID / SI / EditID.
type TxOpID struct {
- CellID tag.ID // target cell or space ID
+ CellID tag.ID // target cell / storage / container ID
AttrID tag.ID // references an attribute or protocol specification
ItemID tag.ID // user-defined UID, SKU, inline value, or element ID
EditID tag.ID // references previous revision(s); see tag.ForkEdit()
@@ -104,6 +104,6 @@ type TxOp struct {
}
type AttrDef struct {
- tag.Spec
+ tag.Expr
Prototype tag.Value
}
diff --git a/amp/api.host.go b/amp/api.host.go
index 391bd78..20b234f 100644
--- a/amp/api.host.go
+++ b/amp/api.host.go
@@ -84,10 +84,10 @@ type Registry interface {
// When a Session is created, its registry starts by importing the Host's registry.
Import(other Registry) error
- // Registers an element value type (tag.Value) as a prototype under its pure scalar element type name (also a valid tag.Spec type expression).
+ // Registers an element value type (tag.Value) as a prototype under its pure scalar element type name (also a valid tag.Expr type expression).
// If an entry already exists (common for a type used by multiple apps), then this is a no-op.
// if registerAs == "", reflect is used find the underlying element type name.
- RegisterPrototype(context tag.Spec, prototype tag.Value, registerAs string) tag.Spec
+ RegisterPrototype(context tag.Expr, prototype tag.Value, registerAs string) tag.Expr
// Registers an app by its UTag, URI, and schemas it supports.
RegisterApp(app *App) error
diff --git a/amp/ski/amp.ski.pb.go b/amp/ski/amp.ski.pb.go
index 51305b3..2c7309d 100644
--- a/amp/ski/amp.ski.pb.go
+++ b/amp/ski/amp.ski.pb.go
@@ -26,31 +26,31 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
-// KeyType identifies how a key operates
-type KeyType int32
+// KeyForm identifies how a key operates
+type KeyForm int32
const (
- KeyType_Unspecified KeyType = 0
- KeyType_SymmetricKey KeyType = 1
- KeyType_AsymmetricKey KeyType = 2
- KeyType_SigningKey KeyType = 3
+ KeyForm_Unspecified KeyForm = 0
+ KeyForm_SymmetricKey KeyForm = 1
+ KeyForm_AsymmetricKey KeyForm = 2
+ KeyForm_SigningKey KeyForm = 3
)
-var KeyType_name = map[int32]string{
- 0: "KeyType_Unspecified",
- 1: "KeyType_SymmetricKey",
- 2: "KeyType_AsymmetricKey",
- 3: "KeyType_SigningKey",
+var KeyForm_name = map[int32]string{
+ 0: "KeyForm_Unspecified",
+ 1: "KeyForm_SymmetricKey",
+ 2: "KeyForm_AsymmetricKey",
+ 3: "KeyForm_SigningKey",
}
-var KeyType_value = map[string]int32{
- "KeyType_Unspecified": 0,
- "KeyType_SymmetricKey": 1,
- "KeyType_AsymmetricKey": 2,
- "KeyType_SigningKey": 3,
+var KeyForm_value = map[string]int32{
+ "KeyForm_Unspecified": 0,
+ "KeyForm_SymmetricKey": 1,
+ "KeyForm_AsymmetricKey": 2,
+ "KeyForm_SigningKey": 3,
}
-func (KeyType) EnumDescriptor() ([]byte, []int) {
+func (KeyForm) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_3fbac0f28ceb772b, []int{0}
}
@@ -335,10 +335,10 @@ func (m *CryptOpOut) GetOpPubKey() []byte {
// KeyInfo exists in two modes/uses:
// 1. Generated/copied from an existing KeyEntry
// 2. Key gen mode: used as a guide to generate a new key
-// a) Fields used: KeyType and CryptoKitID (other fields ignored)
+// a) Fields used: KeyForm and CryptoKitID (other fields ignored)
type KeyInfo struct {
// Specifies the type of key this is (optional)
- KeyType KeyType `protobuf:"varint,1,opt,name=KeyType,proto3,enum=ski.KeyType" json:"KeyType,omitempty"`
+ KeyForm KeyForm `protobuf:"varint,1,opt,name=KeyForm,proto3,enum=ski.KeyForm" json:"KeyForm,omitempty"`
// Specifies which crypto suite to invoke.
CryptoKitID CryptoKitID `protobuf:"varint,2,opt,name=CryptoKitID,proto3,enum=ski.CryptoKitID" json:"CryptoKitID,omitempty"`
// Unix timestamp << 16 ("UTC16") when this key was created (or 0 if not set)
@@ -379,11 +379,11 @@ func (m *KeyInfo) XXX_DiscardUnknown() {
var xxx_messageInfo_KeyInfo proto.InternalMessageInfo
-func (m *KeyInfo) GetKeyType() KeyType {
+func (m *KeyInfo) GetKeyForm() KeyForm {
if m != nil {
- return m.KeyType
+ return m.KeyForm
}
- return KeyType_Unspecified
+ return KeyForm_Unspecified
}
func (m *KeyInfo) GetCryptoKitID() CryptoKitID {
@@ -468,7 +468,7 @@ func (m *KeyRef) GetPubKey() []byte {
// - KeyEntry.PrivKey == nil
// - Fields used: KeyInfo.PubKey (other fields ignored)
// 3. GenerateKeys "guide" mode: KeyInfo used as a guide to generate a new key
-// - Fields used: KeyInfo.KeyType and KeyInfo.CryptoKitID (other fields ignored)
+// - Fields used: KeyInfo.KeyForm and KeyInfo.CryptoKitID (other fields ignored)
type KeyEntry struct {
// Info about this key
KeyInfo *KeyInfo `protobuf:"bytes,1,opt,name=KeyInfo,proto3" json:"KeyInfo,omitempty"`
@@ -806,7 +806,7 @@ func (m *KeyTomeCrypt) GetKeyInfo() *KeyInfo {
}
func init() {
- proto.RegisterEnum("ski.KeyType", KeyType_name, KeyType_value)
+ proto.RegisterEnum("ski.KeyForm", KeyForm_name, KeyForm_value)
proto.RegisterEnum("ski.CryptoKitID", CryptoKitID_name, CryptoKitID_value)
proto.RegisterEnum("ski.HashKitID", HashKitID_name, HashKitID_value)
proto.RegisterEnum("ski.CryptOp", CryptOp_name, CryptOp_value)
@@ -824,68 +824,68 @@ func init() {
func init() { proto.RegisterFile("amp.ski.proto", fileDescriptor_3fbac0f28ceb772b) }
var fileDescriptor_3fbac0f28ceb772b = []byte{
- // 904 bytes of a gzipped FileDescriptorProto
- 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x55, 0x4d, 0x6f, 0xe3, 0x44,
- 0x18, 0xf6, 0xc4, 0xa9, 0x93, 0xbe, 0x49, 0x8b, 0x35, 0x94, 0xae, 0x29, 0x60, 0xa5, 0x01, 0xad,
- 0xa2, 0x0a, 0xad, 0xb4, 0x59, 0x8a, 0x04, 0xe2, 0x40, 0xd3, 0x16, 0x35, 0xf2, 0xaa, 0xa9, 0x26,
- 0xdd, 0x73, 0xe5, 0x26, 0x6f, 0x82, 0xd5, 0xfa, 0x43, 0xb6, 0xb3, 0x8b, 0xf7, 0xc4, 0x0f, 0xe0,
- 0xc0, 0x3f, 0xe0, 0xca, 0x4f, 0xe1, 0x58, 0x89, 0xcb, 0x1e, 0x69, 0x7a, 0xe1, 0x80, 0xb4, 0xfb,
- 0x13, 0xd0, 0x8c, 0xc7, 0xce, 0xb8, 0xfb, 0x71, 0x9b, 0xf7, 0x79, 0xde, 0xcf, 0x67, 0xde, 0xd1,
- 0xc0, 0x86, 0xeb, 0x47, 0x8f, 0x92, 0x2b, 0xef, 0x51, 0x14, 0x87, 0x69, 0x48, 0xf5, 0xe4, 0xca,
- 0xeb, 0xfe, 0x47, 0xa0, 0x75, 0x18, 0x67, 0x51, 0x3a, 0x8a, 0x0e, 0xe2, 0x79, 0x42, 0x1f, 0x42,
- 0x43, 0x9a, 0x16, 0xe9, 0x90, 0xde, 0x66, 0xbf, 0x2d, 0x22, 0x24, 0xc6, 0x0a, 0x92, 0xfe, 0x00,
- 0xe6, 0x11, 0xce, 0xdc, 0xc5, 0x75, 0x2a, 0x90, 0xd0, 0xf1, 0x52, 0xab, 0x26, 0x02, 0xcc, 0x55,
- 0x00, 0x47, 0x87, 0x47, 0xec, 0x2d, 0x4f, 0xba, 0x05, 0x6b, 0x83, 0xc5, 0x6c, 0x18, 0x58, 0x7a,
- 0x87, 0xf4, 0xda, 0x2c, 0x37, 0xe8, 0x2e, 0xac, 0x8d, 0x22, 0x07, 0x33, 0xab, 0xde, 0x21, 0xbd,
- 0x56, 0xbf, 0x25, 0x12, 0x39, 0x98, 0x31, 0x9c, 0xb1, 0x9c, 0xa1, 0x16, 0x34, 0xce, 0x10, 0x63,
- 0xee, 0xb4, 0x26, 0x42, 0x0b, 0x93, 0x7e, 0x05, 0xc6, 0x79, 0xe8, 0xe3, 0x30, 0xb0, 0x0c, 0x11,
- 0xdd, 0x2e, 0xa2, 0x39, 0xca, 0x24, 0xd7, 0xfd, 0x11, 0x40, 0x4e, 0x30, 0x5a, 0xa4, 0x74, 0x1b,
- 0x8c, 0xc1, 0x62, 0x36, 0x5a, 0xa4, 0x62, 0xd6, 0x36, 0x93, 0x16, 0xdd, 0x81, 0xe6, 0x28, 0x3a,
- 0x5b, 0x5c, 0xf2, 0x32, 0x35, 0xc1, 0x94, 0x76, 0xf7, 0x0f, 0x02, 0x0d, 0x07, 0xb3, 0x61, 0x30,
- 0x0b, 0xb9, 0x58, 0xbc, 0x40, 0x16, 0x61, 0x45, 0x2c, 0x89, 0xb1, 0x82, 0xa4, 0x7d, 0xa9, 0x71,
- 0xae, 0xc7, 0x7b, 0x75, 0x52, 0x9d, 0x68, 0x07, 0x5a, 0xe7, 0x9e, 0x8f, 0x87, 0x31, 0xba, 0x29,
- 0x4e, 0x85, 0x50, 0x3a, 0x53, 0x21, 0xde, 0xbd, 0xec, 0xb1, 0x9e, 0x77, 0x2f, 0x3b, 0x1c, 0x80,
- 0x91, 0x8b, 0xc6, 0x73, 0x38, 0x98, 0xc5, 0x5e, 0x30, 0x3f, 0x75, 0x7d, 0x94, 0x43, 0xaa, 0x90,
- 0x92, 0xa3, 0x56, 0xc9, 0xf1, 0x14, 0x9a, 0x0e, 0x66, 0xc7, 0x41, 0x1a, 0x67, 0x72, 0x4a, 0x3e,
- 0xb0, 0xc8, 0xa0, 0x48, 0xcb, 0x31, 0x56, 0xaa, 0xc1, 0xef, 0x26, 0xf6, 0x9e, 0xf3, 0x64, 0x86,
- 0xbc, 0x9b, 0xdc, 0xec, 0xfe, 0x96, 0x6b, 0xc6, 0xab, 0x52, 0x0a, 0x75, 0xa5, 0x19, 0x71, 0xa6,
- 0xbb, 0x50, 0x77, 0x30, 0x4b, 0xac, 0x5a, 0x47, 0xef, 0xb5, 0xfa, 0x1b, 0x45, 0x7a, 0x51, 0x9e,
- 0x09, 0x8a, 0x3e, 0x84, 0xcd, 0x71, 0x18, 0xa7, 0x38, 0x1d, 0x64, 0xb2, 0x61, 0xae, 0x48, 0x93,
- 0xdd, 0x43, 0x69, 0x17, 0xda, 0xa7, 0xf8, 0x02, 0x93, 0xb4, 0x22, 0x4d, 0x05, 0xeb, 0x7a, 0xf9,
- 0xb5, 0x85, 0x3e, 0x52, 0x13, 0x74, 0x86, 0xcf, 0x45, 0x33, 0x3a, 0xe3, 0x47, 0xda, 0x13, 0x93,
- 0xf3, 0x56, 0x8b, 0x7e, 0xca, 0x71, 0x39, 0xc8, 0x4a, 0x96, 0x97, 0x2a, 0x8a, 0x8b, 0x89, 0xf2,
- 0x86, 0x2a, 0x58, 0xf7, 0x35, 0x81, 0xf5, 0xb1, 0x37, 0x3f, 0x41, 0x77, 0x8a, 0x31, 0xfd, 0x1e,
- 0x3e, 0x1a, 0x7b, 0xf3, 0x00, 0xe3, 0xd5, 0x9b, 0x21, 0xef, 0xd9, 0x85, 0xfb, 0x8e, 0xa2, 0x9a,
- 0x80, 0x2a, 0xf7, 0x55, 0xc1, 0xe8, 0xd7, 0xb0, 0x7e, 0xe2, 0x26, 0x3f, 0xe7, 0x5b, 0x66, 0x88,
- 0xcc, 0x9b, 0x22, 0x73, 0x89, 0xb2, 0x95, 0x03, 0xdf, 0xf2, 0xbc, 0xaf, 0xf1, 0x4b, 0xab, 0xd1,
- 0x21, 0xbd, 0x0d, 0x56, 0xda, 0x7c, 0x73, 0xf2, 0xf3, 0x61, 0x38, 0xc5, 0x89, 0xd5, 0x14, 0xb4,
- 0x0a, 0x89, 0xb7, 0x13, 0x4e, 0xb3, 0xf1, 0x4b, 0x6b, 0xbd, 0x43, 0x7a, 0x75, 0x26, 0xad, 0x6e,
- 0x08, 0x6d, 0x29, 0xae, 0xe8, 0x9d, 0xdf, 0x37, 0x37, 0x8a, 0xfb, 0x16, 0xaa, 0x7f, 0x59, 0x6c,
- 0xa8, 0x05, 0x6f, 0xbf, 0xf4, 0x62, 0x79, 0x95, 0xb5, 0x6b, 0x7d, 0x60, 0xed, 0xf6, 0xc2, 0xf2,
- 0x11, 0xd2, 0x07, 0xf0, 0xb1, 0x3c, 0x5e, 0x3c, 0x0b, 0x92, 0x08, 0x27, 0xde, 0xcc, 0xc3, 0xa9,
- 0xa9, 0x51, 0x0b, 0xb6, 0x0a, 0x62, 0x9c, 0xf9, 0x3e, 0xa6, 0xb1, 0x37, 0x71, 0x30, 0x33, 0x09,
- 0xfd, 0x14, 0x3e, 0x29, 0x98, 0x83, 0x44, 0xa5, 0x6a, 0x74, 0x1b, 0x68, 0x19, 0xe4, 0xcd, 0x03,
- 0x2f, 0x98, 0x73, 0x5c, 0xdf, 0xbb, 0xa8, 0xbc, 0x66, 0xba, 0x0b, 0x5f, 0x28, 0xa6, 0x5a, 0x38,
- 0x87, 0x4d, 0x8d, 0x6e, 0x81, 0xa9, 0xba, 0x9c, 0xba, 0x87, 0xd7, 0x26, 0xe1, 0xdd, 0xaa, 0xe8,
- 0xf1, 0x51, 0x7f, 0x7f, 0xff, 0xf1, 0x77, 0x66, 0x6d, 0xef, 0x6f, 0xa2, 0xdc, 0x23, 0xed, 0xc0,
- 0xe7, 0xa5, 0xa1, 0x66, 0x97, 0xa0, 0xa9, 0x51, 0x1b, 0x76, 0x56, 0x1e, 0x4f, 0x71, 0xee, 0x4e,
- 0x32, 0x07, 0x27, 0x13, 0xf7, 0xea, 0xa2, 0xbf, 0xff, 0xad, 0x49, 0x3e, 0xc0, 0xef, 0x3f, 0xee,
- 0xe7, 0x83, 0xae, 0xf8, 0xf1, 0xc9, 0xc1, 0x13, 0x11, 0xa7, 0xbf, 0x03, 0xe7, 0xfe, 0x75, 0xae,
- 0xd9, 0x0a, 0x1f, 0x5c, 0xbb, 0x57, 0xd8, 0xbf, 0x14, 0x21, 0x6b, 0xef, 0xa6, 0x78, 0x94, 0xb1,
- 0xf7, 0x9a, 0x94, 0x5f, 0x0b, 0x35, 0xa1, 0x2d, 0x8f, 0x42, 0x5a, 0x53, 0xe3, 0xb5, 0x0a, 0xe4,
- 0x38, 0x98, 0xf0, 0xd3, 0x38, 0xf3, 0x4d, 0xa2, 0xe2, 0x47, 0x58, 0xe2, 0x35, 0x5e, 0xe8, 0x9e,
- 0xff, 0x79, 0xc8, 0xbf, 0x02, 0x53, 0xa7, 0x9f, 0xc1, 0x83, 0x7b, 0x21, 0x3f, 0xc5, 0xa1, 0x2f,
- 0xc8, 0xba, 0x1a, 0x37, 0xf4, 0xa3, 0x30, 0x4e, 0x9f, 0x25, 0x5e, 0x30, 0x3f, 0x7b, 0x91, 0xf7,
- 0x5e, 0xa6, 0xfc, 0x45, 0xa5, 0x0c, 0xba, 0x03, 0xdb, 0xd5, 0xa8, 0x32, 0x63, 0x83, 0xef, 0x56,
- 0x35, 0x4c, 0x36, 0xd2, 0x1c, 0x7c, 0x73, 0x73, 0x6b, 0x6b, 0xaf, 0x6e, 0x6d, 0xed, 0xcd, 0xad,
- 0x4d, 0x7e, 0x5d, 0xda, 0xe4, 0xcf, 0xa5, 0x4d, 0xfe, 0x5a, 0xda, 0xe4, 0x66, 0x69, 0x93, 0x7f,
- 0x96, 0x36, 0xf9, 0x77, 0x69, 0x6b, 0x6f, 0x96, 0x36, 0xf9, 0xfd, 0xce, 0xd6, 0x6e, 0xee, 0x6c,
- 0xed, 0xd5, 0x9d, 0xad, 0x5d, 0x1a, 0xe2, 0x77, 0x7e, 0xf2, 0x7f, 0x00, 0x00, 0x00, 0xff, 0xff,
- 0x73, 0x07, 0xda, 0x73, 0xae, 0x07, 0x00, 0x00,
-}
-
-func (x KeyType) String() string {
- s, ok := KeyType_name[int32(x)]
+ // 906 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x55, 0xcd, 0x6e, 0xdb, 0x46,
+ 0x10, 0xe6, 0x8a, 0x32, 0x25, 0x8f, 0x64, 0x97, 0xd8, 0xba, 0x0e, 0xeb, 0xb6, 0x84, 0xac, 0x16,
+ 0x81, 0x60, 0x14, 0x01, 0xa2, 0xd4, 0x05, 0x5a, 0xf4, 0x50, 0xcb, 0x76, 0x60, 0x81, 0x81, 0x65,
+ 0xac, 0x9c, 0xb3, 0x41, 0x4b, 0x2b, 0x95, 0xb0, 0x49, 0x0a, 0x24, 0x95, 0x94, 0x39, 0xf5, 0x01,
+ 0x7a, 0xe8, 0x1b, 0xf4, 0xda, 0x47, 0xe9, 0xd1, 0x40, 0x2f, 0x39, 0xd6, 0xf2, 0xa5, 0x87, 0x02,
+ 0xc9, 0x23, 0x04, 0xb3, 0x5c, 0x52, 0x4b, 0x25, 0xf1, 0x6d, 0xe7, 0x9b, 0xbf, 0x6f, 0xbe, 0x9d,
+ 0xc5, 0xc2, 0x86, 0xeb, 0xcf, 0x1e, 0xc5, 0x57, 0xde, 0xa3, 0x59, 0x14, 0x26, 0x21, 0xd5, 0xe3,
+ 0x2b, 0xaf, 0xfd, 0x3f, 0x81, 0xc6, 0x61, 0x94, 0xce, 0x92, 0xc1, 0xec, 0x20, 0x9a, 0xc6, 0xf4,
+ 0x21, 0xd4, 0xa4, 0x69, 0x91, 0x16, 0xe9, 0x6c, 0x76, 0x9b, 0x22, 0x43, 0x62, 0x2c, 0x77, 0xd2,
+ 0x9f, 0xc0, 0x3c, 0xe2, 0x13, 0x77, 0x7e, 0x9d, 0x08, 0x24, 0x74, 0xbc, 0xc4, 0xaa, 0x88, 0x04,
+ 0x73, 0x99, 0x80, 0x68, 0xff, 0x88, 0xbd, 0x17, 0x49, 0xb7, 0x60, 0xad, 0x37, 0x9f, 0xf4, 0x03,
+ 0x4b, 0x6f, 0x91, 0x4e, 0x93, 0x65, 0x06, 0xdd, 0x85, 0xb5, 0xc1, 0xcc, 0xe1, 0xa9, 0x55, 0x6d,
+ 0x91, 0x4e, 0xa3, 0xdb, 0x10, 0x85, 0x1c, 0x9e, 0x32, 0x3e, 0x61, 0x99, 0x87, 0x5a, 0x50, 0x3b,
+ 0xe3, 0x3c, 0xc2, 0xa0, 0x35, 0x91, 0x9a, 0x9b, 0xf4, 0x1b, 0x30, 0xce, 0x43, 0x9f, 0xf7, 0x03,
+ 0xcb, 0x10, 0xd9, 0xcd, 0x3c, 0x1b, 0x51, 0x26, 0x7d, 0xed, 0x9f, 0x01, 0xe4, 0x04, 0x83, 0x79,
+ 0x42, 0xb7, 0xc1, 0xe8, 0xcd, 0x27, 0x83, 0x79, 0x22, 0x66, 0x6d, 0x32, 0x69, 0xd1, 0x1d, 0xa8,
+ 0x0f, 0x66, 0x67, 0xf3, 0x4b, 0x6c, 0x53, 0x11, 0x9e, 0xc2, 0x6e, 0xff, 0x49, 0xa0, 0xe6, 0xf0,
+ 0xb4, 0x1f, 0x4c, 0x42, 0x14, 0xcb, 0xe1, 0xe9, 0xd3, 0x30, 0xf2, 0x4b, 0x62, 0x49, 0x8c, 0xe5,
+ 0x4e, 0xda, 0x95, 0x1a, 0x67, 0x7a, 0x7c, 0x54, 0x27, 0x35, 0x88, 0xb6, 0xa0, 0x71, 0xee, 0xf9,
+ 0xfc, 0x30, 0xe2, 0x6e, 0xc2, 0xc7, 0x42, 0x28, 0x9d, 0xa9, 0x10, 0xb2, 0x97, 0x1c, 0xab, 0x19,
+ 0x7b, 0xc9, 0xb0, 0x07, 0x46, 0x26, 0x1a, 0xd6, 0x70, 0x78, 0x1a, 0x79, 0xc1, 0xf4, 0xd4, 0xf5,
+ 0xb9, 0x1c, 0x52, 0x85, 0x94, 0x1a, 0x95, 0x52, 0x8d, 0x67, 0x50, 0x77, 0x78, 0x7a, 0x1c, 0x24,
+ 0x51, 0x2a, 0xa7, 0xc4, 0x81, 0x45, 0x05, 0x45, 0x5a, 0xc4, 0x58, 0xa1, 0x06, 0xde, 0x4d, 0xe4,
+ 0xbd, 0xc0, 0x62, 0x86, 0xbc, 0x9b, 0xcc, 0x6c, 0xff, 0x9e, 0x69, 0x86, 0x5d, 0x29, 0x85, 0xaa,
+ 0x42, 0x46, 0x9c, 0xe9, 0x2e, 0x54, 0x1d, 0x9e, 0xc6, 0x56, 0xa5, 0xa5, 0x77, 0x1a, 0xdd, 0x8d,
+ 0xbc, 0xbc, 0x68, 0xcf, 0x84, 0x8b, 0x3e, 0x84, 0xcd, 0x61, 0x18, 0x25, 0x7c, 0xdc, 0x4b, 0x25,
+ 0x61, 0x54, 0xa4, 0xce, 0x56, 0x50, 0xda, 0x86, 0xe6, 0x29, 0x7f, 0xc9, 0xe3, 0xa4, 0x24, 0x4d,
+ 0x09, 0x6b, 0x7b, 0x82, 0x0d, 0x6e, 0x04, 0x35, 0x41, 0x67, 0xfc, 0x85, 0x20, 0xa3, 0x33, 0x3c,
+ 0xd2, 0x8e, 0x98, 0x1c, 0xa9, 0xe6, 0x7c, 0x8a, 0x71, 0x11, 0x64, 0x85, 0x17, 0x5b, 0xe5, 0xcd,
+ 0xc5, 0x44, 0x19, 0xa1, 0x12, 0xd6, 0x7e, 0x43, 0x60, 0x7d, 0xe8, 0x4d, 0x4f, 0xb8, 0x3b, 0xe6,
+ 0x11, 0xfd, 0x11, 0x3e, 0x19, 0x7a, 0xd3, 0x80, 0x47, 0xcb, 0x37, 0x43, 0x3e, 0xb2, 0x0b, 0xab,
+ 0x81, 0xa2, 0x9b, 0x80, 0x4a, 0xf7, 0x55, 0xc2, 0xe8, 0xb7, 0xb0, 0x7e, 0xe2, 0xc6, 0xbf, 0x64,
+ 0x5b, 0x66, 0x88, 0xca, 0x9b, 0xa2, 0x72, 0x81, 0xb2, 0x65, 0x00, 0x6e, 0x79, 0xc6, 0x6b, 0xf8,
+ 0xca, 0xaa, 0xb5, 0x48, 0x67, 0x83, 0x15, 0x36, 0x6e, 0x4e, 0x76, 0x3e, 0x0c, 0xc7, 0x7c, 0x64,
+ 0xd5, 0x85, 0x5b, 0x85, 0xc4, 0xdb, 0x09, 0xc7, 0xe9, 0xf0, 0x95, 0xb5, 0xde, 0x22, 0x9d, 0x2a,
+ 0x93, 0x56, 0x3b, 0x84, 0xa6, 0x14, 0x57, 0x70, 0xc7, 0xfb, 0x46, 0x23, 0xbf, 0x6f, 0xa1, 0xfa,
+ 0xd7, 0xf9, 0x86, 0x5a, 0xf0, 0xfe, 0x4b, 0xcf, 0x97, 0x57, 0x59, 0xbb, 0xc6, 0x3d, 0x6b, 0xb7,
+ 0x17, 0x16, 0x8f, 0x90, 0x3e, 0x80, 0x4f, 0xe5, 0xf1, 0xe2, 0x79, 0x10, 0xcf, 0xf8, 0xc8, 0x9b,
+ 0x78, 0x7c, 0x6c, 0x6a, 0xd4, 0x82, 0xad, 0xdc, 0x31, 0x4c, 0x7d, 0x9f, 0x27, 0x91, 0x37, 0x72,
+ 0x78, 0x6a, 0x12, 0xfa, 0x39, 0x7c, 0x96, 0x7b, 0x0e, 0x62, 0xd5, 0x55, 0xa1, 0xdb, 0x40, 0x8b,
+ 0x24, 0x6f, 0x1a, 0x78, 0xc1, 0x14, 0x71, 0x7d, 0xef, 0xa2, 0xf4, 0x9a, 0xe9, 0x2e, 0x7c, 0xa5,
+ 0x98, 0x6a, 0xe3, 0x0c, 0x36, 0x35, 0xba, 0x05, 0xa6, 0x1a, 0x72, 0xea, 0x1e, 0x5e, 0x9b, 0x04,
+ 0xd9, 0xaa, 0xe8, 0xf1, 0x51, 0x77, 0x7f, 0xff, 0xf1, 0x0f, 0x66, 0x65, 0xef, 0x1f, 0xa2, 0xdc,
+ 0x23, 0x6d, 0xc1, 0x97, 0x85, 0xa1, 0x56, 0x97, 0xa0, 0xa9, 0x51, 0x1b, 0x76, 0x96, 0x11, 0xcf,
+ 0xf8, 0xd4, 0x1d, 0xa5, 0x0e, 0x1f, 0x8d, 0xdc, 0xab, 0x8b, 0xee, 0xfe, 0xf7, 0x26, 0xb9, 0xc7,
+ 0xbf, 0xff, 0xb8, 0x9b, 0x0d, 0xba, 0xf4, 0x0f, 0x4f, 0x0e, 0x9e, 0x88, 0x3c, 0xfd, 0x03, 0x38,
+ 0xc6, 0x57, 0x51, 0xb3, 0x25, 0xde, 0xbb, 0x76, 0xaf, 0x78, 0xf7, 0x52, 0xa4, 0xac, 0x7d, 0xd8,
+ 0x85, 0x59, 0xc6, 0xde, 0x1b, 0x52, 0x7c, 0x2d, 0xd4, 0x84, 0xa6, 0x3c, 0x0a, 0x69, 0x4d, 0x0d,
+ 0x7b, 0xe5, 0xc8, 0x71, 0x30, 0xc2, 0xd3, 0x30, 0xf5, 0x4d, 0xa2, 0xe2, 0x47, 0xbc, 0xc0, 0x2b,
+ 0xd8, 0x68, 0x25, 0xfe, 0x3c, 0xc4, 0xaf, 0xc0, 0xd4, 0xe9, 0x17, 0xf0, 0x60, 0x25, 0xe5, 0x69,
+ 0x14, 0xfa, 0xc2, 0x59, 0x55, 0xf3, 0xfa, 0xfe, 0x2c, 0x8c, 0x92, 0xe7, 0xb1, 0x17, 0x4c, 0xcf,
+ 0x5e, 0x66, 0xdc, 0x8b, 0x92, 0xbf, 0xaa, 0x2e, 0x83, 0xee, 0xc0, 0x76, 0x39, 0xab, 0xa8, 0x58,
+ 0xc3, 0xdd, 0x2a, 0xa7, 0x49, 0x22, 0xf5, 0xde, 0x77, 0x37, 0xb7, 0xb6, 0xf6, 0xfa, 0xd6, 0xd6,
+ 0xde, 0xde, 0xda, 0xe4, 0xb7, 0x85, 0x4d, 0xfe, 0x5a, 0xd8, 0xe4, 0xef, 0x85, 0x4d, 0x6e, 0x16,
+ 0x36, 0xf9, 0x77, 0x61, 0x93, 0xff, 0x16, 0xb6, 0xf6, 0x76, 0x61, 0x93, 0x3f, 0xee, 0x6c, 0xed,
+ 0xe6, 0xce, 0xd6, 0x5e, 0xdf, 0xd9, 0xda, 0xa5, 0x21, 0x7e, 0xe7, 0x27, 0xef, 0x02, 0x00, 0x00,
+ 0xff, 0xff, 0x8b, 0x2b, 0xf4, 0x02, 0xae, 0x07, 0x00, 0x00,
+}
+
+func (x KeyForm) String() string {
+ s, ok := KeyForm_name[int32(x)]
if ok {
return s
}
@@ -997,7 +997,7 @@ func (this *KeyInfo) Equal(that interface{}) bool {
} else if this == nil {
return false
}
- if this.KeyType != that1.KeyType {
+ if this.KeyForm != that1.KeyForm {
return false
}
if this.CryptoKitID != that1.CryptoKitID {
@@ -1243,7 +1243,7 @@ func (this *KeyInfo) GoString() string {
}
s := make([]string, 0, 8)
s = append(s, "&ski.KeyInfo{")
- s = append(s, "KeyType: "+fmt.Sprintf("%#v", this.KeyType)+",\n")
+ s = append(s, "KeyForm: "+fmt.Sprintf("%#v", this.KeyForm)+",\n")
s = append(s, "CryptoKitID: "+fmt.Sprintf("%#v", this.CryptoKitID)+",\n")
s = append(s, "TimeCreated: "+fmt.Sprintf("%#v", this.TimeCreated)+",\n")
s = append(s, "PubKey: "+fmt.Sprintf("%#v", this.PubKey)+",\n")
@@ -1487,8 +1487,8 @@ func (m *KeyInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i--
dAtA[i] = 0x10
}
- if m.KeyType != 0 {
- i = encodeVarintAmpSki(dAtA, i, uint64(m.KeyType))
+ if m.KeyForm != 0 {
+ i = encodeVarintAmpSki(dAtA, i, uint64(m.KeyForm))
i--
dAtA[i] = 0x8
}
@@ -1861,8 +1861,8 @@ func (m *KeyInfo) Size() (n int) {
}
var l int
_ = l
- if m.KeyType != 0 {
- n += 1 + sovAmpSki(uint64(m.KeyType))
+ if m.KeyForm != 0 {
+ n += 1 + sovAmpSki(uint64(m.KeyForm))
}
if m.CryptoKitID != 0 {
n += 1 + sovAmpSki(uint64(m.CryptoKitID))
@@ -2044,7 +2044,7 @@ func (this *KeyInfo) String() string {
return "nil"
}
s := strings.Join([]string{`&KeyInfo{`,
- `KeyType:` + fmt.Sprintf("%v", this.KeyType) + `,`,
+ `KeyForm:` + fmt.Sprintf("%v", this.KeyForm) + `,`,
`CryptoKitID:` + fmt.Sprintf("%v", this.CryptoKitID) + `,`,
`TimeCreated:` + fmt.Sprintf("%v", this.TimeCreated) + `,`,
`PubKey:` + fmt.Sprintf("%v", this.PubKey) + `,`,
@@ -2521,9 +2521,9 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error {
switch fieldNum {
case 1:
if wireType != 0 {
- return fmt.Errorf("proto: wrong wireType = %d for field KeyType", wireType)
+ return fmt.Errorf("proto: wrong wireType = %d for field KeyForm", wireType)
}
- m.KeyType = 0
+ m.KeyForm = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAmpSki
@@ -2533,7 +2533,7 @@ func (m *KeyInfo) Unmarshal(dAtA []byte) error {
}
b := dAtA[iNdEx]
iNdEx++
- m.KeyType |= KeyType(b&0x7F) << shift
+ m.KeyForm |= KeyForm(b&0x7F) << shift
if b < 0x80 {
break
}
diff --git a/amp/ski/amp.ski.proto b/amp/ski/amp.ski.proto
index a2ad33f..6157e5f 100644
--- a/amp/ski/amp.ski.proto
+++ b/amp/ski/amp.ski.proto
@@ -3,13 +3,13 @@ syntax = "proto3";
package ski;
-// KeyType identifies how a key operates
-enum KeyType {
- KeyType_Unspecified = 0;
+// KeyForm identifies how a key operates
+enum KeyForm {
+ KeyForm_Unspecified = 0;
- KeyType_SymmetricKey = 1;
- KeyType_AsymmetricKey = 2;
- KeyType_SigningKey = 3;
+ KeyForm_SymmetricKey = 1;
+ KeyForm_AsymmetricKey = 2;
+ KeyForm_SigningKey = 3;
}
// CryptoKitID identifies an encryption suite that implements ski.CryptoKit
@@ -123,11 +123,11 @@ message CryptOpOut {
// KeyInfo exists in two modes/uses:
// 1) Generated/copied from an existing KeyEntry
// 2) Key gen mode: used as a guide to generate a new key
-// a) Fields used: KeyType and CryptoKitID (other fields ignored)
+// a) Fields used: KeyForm and CryptoKitID (other fields ignored)
message KeyInfo {
// Specifies the type of key this is (optional)
- KeyType KeyType = 1;
+ KeyForm KeyForm = 1;
// Specifies which crypto suite to invoke.
CryptoKitID CryptoKitID = 2;
@@ -160,7 +160,7 @@ message KeyRef {
// - KeyEntry.PrivKey == nil
// - Fields used: KeyInfo.PubKey (other fields ignored)
// 3) GenerateKeys "guide" mode: KeyInfo used as a guide to generate a new key
-// - Fields used: KeyInfo.KeyType and KeyInfo.CryptoKitID (other fields ignored)
+// - Fields used: KeyInfo.KeyForm and KeyInfo.CryptoKitID (other fields ignored)
message KeyEntry {
// Info about this key
diff --git a/amp/ski/api.ski.go b/amp/ski/api.ski.go
index 8586844..9a26089 100644
--- a/amp/ski/api.ski.go
+++ b/amp/ski/api.ski.go
@@ -26,7 +26,7 @@ type CryptoKit interface {
// CryptoKitID univeserally identifies a specific crypto suite and version.
CryptoKitID() CryptoKitID
- // Pre: ioEntry.KeyType, .KeyDomain, .CryptoKitID, and .TimeCreated are set.
+ // Pre: ioEntry.KeyForm, .KeyDomain, .CryptoKitID, and .TimeCreated are set.
// inRequestedKeySz is the requested length of the private key (ignored for some implementations)
GenerateNewKey(
inRequestedKeySz int,
@@ -176,7 +176,7 @@ type EnclaveSession interface {
// Note: incoming duplicate key entries are ignored/dropped.
//ImportKeys(srcTome *KeyTome) error
- // Generates a new KeyEntry for each entry in srcTome (based on the entry's KeyType and CryptoKitID, ignoring the rest) and merges it
+ // Generates a new KeyEntry for each entry in srcTome (based on the entry's KeyForm and CryptoKitID, ignoring the rest) and merges it
// with the host KeyTome. A copy of each newly generated entry (except for PrivKey) is placed into result KeyTome.
// See "KeyGen mode" notes where KeyEntry is declared.
GenerateKeys(srcTome *KeyTome) (*KeyTome, error)
diff --git a/amp/ski/ski.support.go b/amp/ski/ski.support.go
index 253c07d..d2853ba 100644
--- a/amp/ski/ski.support.go
+++ b/amp/ski/ski.support.go
@@ -54,7 +54,7 @@ func CompareKeyInfo(a, b *KeyInfo) int {
if diff == 0 {
diff = int(b.TimeCreated - a.TimeCreated) // Reverse time for newer keys to appear first
if diff == 0 {
- diff = int(a.KeyType - b.KeyType)
+ diff = int(a.KeyForm - b.KeyForm)
if diff == 0 {
diff = int(a.CryptoKitID - b.CryptoKitID)
}
@@ -599,7 +599,7 @@ func (tome *KeyTome) GenerateFork(
newEntry := &KeyEntry{
KeyInfo: &KeyInfo{
- KeyType: srcInfo.KeyType,
+ KeyForm: srcInfo.KeyForm,
CryptoKitID: curKitID,
TimeCreated: int64(timeCreated),
},
@@ -613,7 +613,7 @@ func (tome *KeyTome) GenerateFork(
if err != nil {
return nil, err
}
- if srcInfo.KeyType != newEntry.KeyInfo.KeyType || curKitID != newEntry.KeyInfo.CryptoKitID {
+ if srcInfo.KeyForm != newEntry.KeyInfo.KeyForm || curKitID != newEntry.KeyInfo.CryptoKitID {
return nil,amp.ErrCode_KeyGenerationFailed.Error("generate key altered key type")
}
@@ -632,7 +632,7 @@ func (entry *KeyEntry) EqualTo(other *KeyEntry) bool {
a := entry.KeyInfo
b := entry.KeyInfo
- return a.KeyType != b.KeyType ||
+ return a.KeyForm != b.KeyForm ||
a.CryptoKitID != b.CryptoKitID ||
a.TimeCreated != b.TimeCreated ||
!bytes.Equal(a.PubKey, b.PubKey) ||
@@ -752,7 +752,7 @@ func GenerateNewKeys(
}
newKey := &KeyEntry{
- KeyType: keySpec.KeyType,
+ KeyForm: keySpec.KeyForm,
CryptoKit: kit.CryptoKit,
TimeCreated: timeCreated,
}
@@ -806,7 +806,7 @@ func GenerateNewKey(
return nil, amp.ErrCode_AssertFailed.Error("no keys returned")
}
- if kr.Keys[0].KeyInfo.KeyType != inKeyInfo.KeyType {
+ if kr.Keys[0].KeyInfo.KeyForm != inKeyInfo.KeyForm {
return nil, amp.ErrCode_AssertFailed.Error("unexpected key type")
}
@@ -863,7 +863,7 @@ func (P *PayloadPacker) ResetSession(
if err != nil {
return err
}
- if keyEntry.KeyType != KeyType_SigningKey {
+ if keyEntry.KeyForm != KeyForm_SigningKey {
return amp.ErrCode_SessionNotReady.Error("not a signing key")
}
@@ -1125,7 +1125,7 @@ func (U *PayloadUnpacker) UnpackAndVerify(
out.HashSig = inSignedBuf[sigPos:sigEnd]
out.Body = inSignedBuf[bodyPos:bodyEnd]
out.Signer.PubKey = hdr.SignerPubKey
- out.Signer.KeyType = KeyType_SigningKey
+ out.Signer.KeyForm = KeyForm_SigningKey
out.Signer.CryptoKitID = hdr.SignerCryptoKit
return err
diff --git a/amp/ski/ski.support.test.go b/amp/ski/ski.support.test.go
index dbb390d..17fd7c3 100644
--- a/amp/ski/ski.support.test.go
+++ b/amp/ski/ski.support.test.go
@@ -92,7 +92,7 @@ func testKitWithSizes(kit CryptoKit, inKeyLen, inMsgLen int) {
** Symmetric test
**/
{
- entry.KeyInfo.KeyType = KeyType_SymmetricKey
+ entry.KeyInfo.KeyForm = KeyForm_SymmetricKey
err := kit.GenerateNewKey(inKeyLen, reader, &entry)
if !amp.IsError(err, amp.ErrCode_Unimplemented) {
if err != nil {
@@ -139,7 +139,7 @@ func testKitWithSizes(kit CryptoKit, inKeyLen, inMsgLen int) {
** Asymmetric test
**/
{
- entry.KeyInfo.KeyType = KeyType_AsymmetricKey
+ entry.KeyInfo.KeyForm = KeyForm_AsymmetricKey
err := kit.GenerateNewKey(inKeyLen, reader, &entry)
if !amp.IsError(err, amp.ErrCode_Unimplemented) {
if err != nil {
@@ -195,7 +195,7 @@ func testKitWithSizes(kit CryptoKit, inKeyLen, inMsgLen int) {
** Signing test
**/
{
- entry.KeyInfo.KeyType = KeyType_SigningKey
+ entry.KeyInfo.KeyForm = KeyForm_SigningKey
err := kit.GenerateNewKey(inKeyLen, reader, &entry)
if !amp.IsError(err, amp.ErrCode_Unimplemented) {
if err != nil {
diff --git a/amp/std/std.attrs.go b/amp/std/std.attrs.go
index fd17769..b97f154 100644
--- a/amp/std/std.attrs.go
+++ b/amp/std/std.attrs.go
@@ -13,11 +13,11 @@ var (
LoginResponseSpec = amp.AttrSpec.With("LoginResponse").ID
LoginCheckpointSpec = amp.AttrSpec.With("LoginCheckpoint").ID
- CellChildren = amp.AttrSpec.With("children.TagID") // ID suffix denotes SeriesIndex is used to store a CellID
+ CellChildren = amp.AttrSpec.With("children.Tag.ID") // ID suffix denotes SeriesIndex is used to store a CellID
CellProperties = amp.AttrSpec.With("cell-properties")
LaunchURL = amp.AttrSpec.With("LaunchURL").ID
- CellProperty = tag.Spec{}.With("cell-property")
+ CellProperty = tag.Expr{}.With("cell-property")
TextTag = CellProperty.With("text.Tag")
CellLabel = TextTag.With("label").ID
CellCaption = TextTag.With("caption").ID
@@ -25,7 +25,7 @@ var (
CellCollection = TextTag.With("collection").ID
CellAuthor = TextTag.With("author").ID
- CellPropertyTagID = CellProperty.With("TagID")
+ CellPropertyTagID = CellProperty.With("Tag.ID")
OrderByPlayID = CellPropertyTagID.With("order-by.play").ID
OrderByTimeID = CellPropertyTagID.With("order-by.time").ID
OrderByGeoID = CellPropertyTagID.With("order-by.geo").ID
@@ -74,15 +74,11 @@ func TagsForImageURL(imageURL string) *amp.Tags {
}
}
-type PinnableAttr struct {
- Spec tag.Spec
-}
-
func (v *Position) MarshalToStore(in []byte) (out []byte, err error) {
return amp.MarshalPbToStore(v, in)
}
-func (v *Position) TagSpec() tag.Spec {
+func (v *Position) TagExpr() tag.Expr {
return amp.AttrSpec.With("Position")
}
@@ -94,7 +90,7 @@ func (v *FSInfo) MarshalToStore(in []byte) (out []byte, err error) {
return amp.MarshalPbToStore(v, in)
}
-func (v *FSInfo) TagSpec() tag.Spec {
+func (v *FSInfo) TagExpr() tag.Expr {
return amp.AttrSpec.With("FSInfo")
}
diff --git a/stdlib/bufs/encoding.go b/stdlib/bufs/encoding.go
index fa4a74a..06bbb20 100644
--- a/stdlib/bufs/encoding.go
+++ b/stdlib/bufs/encoding.go
@@ -11,11 +11,17 @@ import (
"reflect"
)
-// GeohashBase32Alphabet is the standard geo-hash alphabet used for Base32Encoding.
-// It chooses particular characters that are not visually similar to each other.
-//
-// https://en.wikipedia.org/wiki/Geohash
-const GeohashBase32Alphabet = "0123456789bcdefghjkmnpqrstuvwxyz"
+const (
+ // GeohashBase32Alphabet is the standard geo-hash alphabet used for Base32Encoding.
+ // It chooses particular characters that are not visually similar to each other.
+ //
+ // Although a geohash is case insensitive, common convention is UPPER CASE
+ // since they are read aloud as if an acronym (versus spoken as a word or syllable).
+ //
+ // https://en.wikipedia.org/wiki/Geohash
+ GeohashBase32Alphabet = "0123456789BCDEFGHJKMNPQRSTUVWXYZ"
+ GeohashBase32Alphabet_Lower = "0123456789bcdefghjkmnpqrstuvwxyz"
+)
var (
// Base32Encoding is used to encode/decode binary buffer to/from base 32
diff --git a/stdlib/tag/api.tag.go b/stdlib/tag/api.tag.go
index b4deeac..d6c98b6 100644
--- a/stdlib/tag/api.tag.go
+++ b/stdlib/tag/api.tag.go
@@ -8,23 +8,27 @@ type ID [3]uint64
// Specifies a set of tag literals and its corresponding tag.ID.
//
-// tag.Spec := "[{utf8_tag_literal}[TagDelimiters]*]*"
-type Spec struct {
+// tag.Expr := "[{TagOp}*[{utf8_token}]*"
+type Expr struct {
ID ID
- Canonic string
+ Canonic string // UTF-8 encoded canonical tag expression
}
const (
- // TagDelimiters separate utf8 tag literals in tag strings.
- TagDelimiters = `[/\\\.+:\s\~]+`
+ PackageTags = "amp.spec.tag.v.0.8"
+
+ WithDelimiters = `[\.+\s,\:\!\?]+` // commutative (symmetric) binary delimiters
+ ThenDelimiters = `[\-/\\\~\^\@]+` // non-commutative binary or unary delimiter
+
+ GroupDelimiters = `[]()<>{}¿?¡!` // TODO group delimiter pairs
)
// tag.Value wraps a data element type, exposing tags, serialization, and instantiation methods.
type Value interface {
ValuePb
- // Returns the element type name (a scalar tag.Spec).
- TagSpec() Spec
+ // Returns the element type name (a scalar tag.Expr).
+ TagExpr() Expr
// Marshals this Value to a buffer, reallocating if needed.
MarshalToStore(in []byte) (out []byte, err error)
diff --git a/stdlib/tag/gold/001.welcome-to-tags.in.txt b/stdlib/tag/gold/001.welcome-to-tags.in.txt
new file mode 100644
index 0000000..10a554c
--- /dev/null
+++ b/stdlib/tag/gold/001.welcome-to-tags.in.txt
@@ -0,0 +1,76 @@
+
+Hello World!
+Hello, World!
+hello world
+world hello
+World, hello.
+
+Hello and welcome to tags!
+hello, and welcome to tags!
+hello, and Welcome to tags!!
+hello, and..welcome to... tags.
+hello+and+welcome+to+tags
+
+
+UTF8 whitespace, commas, +, and . and : denote the "with" operator. This operator adds the hash of each operand and is also therefore commutative.
+
+Text having "homophone case" or "homophonic case" means its component words are considered interchangeable with words that sound the same but have different spelling.
+
+The words Center, center, centre, and Centre are homophonic and should have the same hash.
+The words center, Center, Centre, and centre are homophonic and should have the same hash.
+The words Centre, centre, center, and Center are homophonic and should have the same hash.
+
+This has very helpful implications for those with sight or hearing impairments, or in search result ranking since the query word order is usually less important the presence of particular words, especially once there are dozen words or more.
+
+However: dashes and slashes are order dependent!? Yes, order-dependent!
+However, dashes and slashes are order dependent?! yes, order-dependent
+However, Slashes and dashes are order dependent? Yes, order-dependent
+However: Order-dependent? Yes, slashes, and dashes are order dependent.
+however: dashes and slashes are order-dependent! yES! Order dependent!
+
+However: dependent-order? Yes, slashes and dashes are order dependent.
+However: Slashes and dashes are order dependent. Yes, dependent-order?
+-order dependent, yes. Slashes and dashes are order dependent. However.
+
+Acronyms like NBA, NFL, USA, CIA, PRC, and EU are capitalized since they are spoken letter by letter.
+
+Words that are not upper case, are considered spoken or otherwise phonetic.
+
+This also means we can communicate proper nouns and titles easily, such as A Game of Thrones
+This also means we can communicate proper nouns and titles easily, such as Game of Thrones, A.
+This also means we can communicate proper nouns and titles easily, such as a Game Of Thrones.
+
+Notice how acronyms are spoken differently and have their own unique meanings, so that means ALL-CAPS should be used intentionally.
+
+ADA is an acronym for the Americans with Disabilities Act, Ms. Ada is a computer programmer.
+ADA is an acronym for the Americans with Disabilities Act. ms ada is a computer programmer!
+ADA is an acronym for the Americans with Disabilities Act. Ada is a computer programmer, Ms!
+ADA is an acronym for the Americans With Disabilities Act, A computer programmer, Ms. ada is.
+
+Dig into the amp SDK today!
+Dig into the amp.SDK today!
+Dig into the Amp SDK today!
+
+
+Yoda said this is not a drill.
+Yoda said, a drill this is not.
+Yoda said, a drill this is not!
+a drill this is not, Yoda said!
+said a drill, this is not Yoda.
+said a drill, is this not Yoda?
+said a drill: Is this not Yoda?
+Said a drill,: Is this not Yoda??
+
+
+Dots are the canonical way, ya know. after a dozen words, 24 bytes is 2^192!
+Ya know, dots are the canonical way. after a dozen words, 24 bytes is 2^192!
+
+
+The 24-byte tag.ID you see to the left is 2^192 wide (in base 32). For reference, a Bitcoin address is 20 bytes.
+
+Base16 of the ID above (8kj00c8gw8406tugx9bx417whqj3y0qkg) is 160 bits wide. The leading 32 bits are part of a "minting" when a tag is made decidedly private.
+
+The number of possible hashes for a string of 10 words randomly chosen from the worlds dictionaries well over a million words. Even with the English dictionary's 200,000 words, there are 10^50 (2^160) outputs.
+
+
+TODO: go get github.com/alecthomas/participle/v2 -- for tags.Parse() implementation?
diff --git a/stdlib/tag/gold/001.welcome-to-tags.out.txt b/stdlib/tag/gold/001.welcome-to-tags.out.txt
new file mode 100644
index 0000000..44bf591
--- /dev/null
+++ b/stdlib/tag/gold/001.welcome-to-tags.out.txt
@@ -0,0 +1,130 @@
+ amp.spec.tag.v.0.8 . ✙ בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ ✙ .
+9FDP7NU5U8N2PQU8BHSNUF82B77BBZUQE amp.spec.tag.v.0.8.✙.בְּרֵאשִׁ֖ית.בָּרָ֣א.אֱלֹהִ֑ים.אֵ֥ת.הַשָּׁמַ֖יִם.וְאֵ֥ת.הָאָֽרֶץ.✙
+
+ Hello World!
+ B3EJD9HGSN053Z2TWV6920UP70HDZPNP hello.world
+ Hello, World!
+ B3EJD9HGSN053Z2TWV6920UP70HDZPNP hello.world
+ hello world
+ B3EJD9HGSN053Z2TWV6920UP70HDZPNP hello.world
+ world hello
+ B3EJD9HGSN053Z2TWV6920UP70HDZPNP world.hello
+ World, hello.
+ B3EJD9HGSN053Z2TWV6920UP70HDZPNP world.hello
+
+ Hello and welcome to tags!
+39ZRS85V2W78NZ5NE13YWFHUHJSKRRX3R hello.and.welcome.to.tags
+ hello, and welcome to tags!
+39ZRS85V2W78NZ5NE13YWFHUHJSKRRX3R hello.and.welcome.to.tags
+ hello, and Welcome to tags!!
+39ZRS85V2W78NZ5NE13YWFHUHJSKRRX3R hello.and.welcome.to.tags
+ hello, and..welcome to... tags.
+39ZRS85V2W78NZ5NE13YWFHUHJSKRRX3R hello.and.welcome.to.tags
+ hello+and+welcome+to+tags
+39ZRS85V2W78NZ5NE13YWFHUHJSKRRX3R hello.and.welcome.to.tags
+
+
+ UTF8 whitespace, commas, +, and . and : denote the "with" operator. This operator adds the hash of each operand and is also therefore commutative.
+9J5QZPJ2XGSNR0NHH7UF72J36FFD5N46G UTF8.whitespace.commas.and.and.denote.the."with".operator.this.operator.adds.the.hash.of.each.operand.and.is.also.therefore.commutative
+
+ Text having "homophone case" or "homophonic case" means its component words are considered interchangeable with words that sound the same but have different spelling.
+BNVBK7822R57ZDWVFBT5BM82FTSMP02VD text.having."homophone.case".or."homophonic.case".means.its.component.words.are.considered.interchangeable.with.words.that.sound.the.same.but.have.different.spelling
+
+ The words Center, center, centre, and Centre are homophonic and should have the same hash.
+7E26XPRYV8BYUSJEU5EUUCPW538SG320Z the.words.center.center.centre.and.centre.are.homophonic.and.should.have.the.same.hash
+ The words center, Center, Centre, and centre are homophonic and should have the same hash.
+7E26XPRYV8BYUSJEU5EUUCPW538SG320Z the.words.center.center.centre.and.centre.are.homophonic.and.should.have.the.same.hash
+ The words Centre, centre, center, and Center are homophonic and should have the same hash.
+7E26XPRYV8BYUSJEU5EUUCPW538SG320Z the.words.centre.centre.center.and.center.are.homophonic.and.should.have.the.same.hash
+
+ This has very helpful implications for those with sight or hearing impairments, or in search result ranking since the query word order is usually less important the presence of particular words, especially once there are dozen words or more.
+HNGM76C66X9WYF9G32P0G5T2ZMZ52WHWE this.has.very.helpful.implications.for.those.with.sight.or.hearing.impairments.or.in.search.result.ranking.since.the.query.word.order.is.usually.less.important.the.presence.of.particular.words.especially.once.there.are.dozen.words.or.more
+
+ However: dashes and slashes are order dependent!? Yes, order-dependent!
+36711JP6E0TBK2Z84NS5WJ8NNKEWB7G3P however.dashes.and.slashes.are.order.dependent.yes.order-dependent
+ However, dashes and slashes are order dependent?! yes, order-dependent
+36711JP6E0TBK2Z84NS5WJ8NNKEWB7G3P however.dashes.and.slashes.are.order.dependent.yes.order-dependent
+ However, Slashes and dashes are order dependent? Yes, order-dependent
+36711JP6E0TBK2Z84NS5WJ8NNKEWB7G3P however.slashes.and.dashes.are.order.dependent.yes.order-dependent
+ However: Order-dependent? Yes, slashes, and dashes are order dependent.
+36711JP6E0TBK2Z84NS5WJ8NNKEWB7G3P however.order-dependent.yes.slashes.and.dashes.are.order.dependent
+ however: dashes and slashes are order-dependent! yES! Order dependent!
+36711JP6E0TBK2Z84NS5WJ8NNKEWB7G3P however.dashes.and.slashes.are.order-dependent.yes.order.dependent
+
+ However: dependent-order? Yes, slashes and dashes are order dependent.
+4FCMDX3008CJD7PD9QJZZQT80X82NTVYC however.dependent-order.yes.slashes.and.dashes.are.order.dependent
+ However: Slashes and dashes are order dependent. Yes, dependent-order?
+4FCMDX3008CJD7PD9QJZZQT80X82NTVYC however.slashes.and.dashes.are.order.dependent.yes.dependent-order
+ -order dependent, yes. Slashes and dashes are order dependent. However.
+4FCMDX3008CJD7PD9QJZZQT80X82NTVYC -order.dependent.yes.slashes.and.dashes.are.order.dependent.however
+
+ Acronyms like NBA, NFL, USA, CIA, PRC, and EU are capitalized since they are spoken letter by letter.
+713VSQXU2V4JVRQQG2DMGNFS0CDRBDN4K acronyms.like.NBA.NFL.USA.CIA.PRC.and.EU.are.capitalized.since.they.are.spoken.letter.by.letter
+
+ Words that are not upper case, are considered spoken or otherwise phonetic.
+2VV31GCDGVHJP4VHZFGU7FN85P8GP660W words.that.are.not.upper.case.are.considered.spoken.or.otherwise.phonetic
+
+ This also means we can communicate proper nouns and titles easily, such as A Game of Thrones
+9X1QZ2F0P8ET35Q15H94BS0RN83Q4J050 this.also.means.we.can.communicate.proper.nouns.and.titles.easily.such.as.a.game.of.thrones
+ This also means we can communicate proper nouns and titles easily, such as Game of Thrones, A.
+9X1QZ2F0P8ET35Q15H94BS0RN83Q4J050 this.also.means.we.can.communicate.proper.nouns.and.titles.easily.such.as.game.of.thrones.a
+ This also means we can communicate proper nouns and titles easily, such as a Game Of Thrones.
+9X1QZ2F0P8ET35Q15H94BS0RN83Q4J050 this.also.means.we.can.communicate.proper.nouns.and.titles.easily.such.as.a.game.of.thrones
+
+ Notice how acronyms are spoken differently and have their own unique meanings, so that means ALL-CAPS should be used intentionally.
+9NWT2RZYNHUQQQZUEX71T04N9MJZ9NTNK notice.how.acronyms.are.spoken.differently.and.have.their.own.unique.meanings.so.that.means.ALL-CAPS.should.be.used.intentionally
+
+ ADA is an acronym for the Americans with Disabilities Act, Ms. Ada is a computer programmer.
+7RBXE95STWGNE346S007PGSU2KZQZ2Y1E ADA.is.an.acronym.for.the.americans.with.disabilities.act.ms.ada.is.a.computer.programmer
+ ADA is an acronym for the Americans with Disabilities Act. ms ada is a computer programmer!
+7RBXE95STWGNE346S007PGSU2KZQZ2Y1E ADA.is.an.acronym.for.the.americans.with.disabilities.act.ms.ada.is.a.computer.programmer
+ ADA is an acronym for the Americans with Disabilities Act. Ada is a computer programmer, Ms!
+7RBXE95STWGNE346S007PGSU2KZQZ2Y1E ADA.is.an.acronym.for.the.americans.with.disabilities.act.ada.is.a.computer.programmer.ms
+ ADA is an acronym for the Americans With Disabilities Act, A computer programmer, Ms. ada is.
+7RBXE95STWGNE346S007PGSU2KZQZ2Y1E ADA.is.an.acronym.for.the.americans.with.disabilities.act.a.computer.programmer.ms.ada.is
+
+ Dig into the amp SDK today!
+2YX2T7C2GP0U21SH339FBHZJC3UR2CTTH dig.into.the.amp.SDK.today
+ Dig into the amp.SDK today!
+2YX2T7C2GP0U21SH339FBHZJC3UR2CTTH dig.into.the.amp.SDK.today
+ Dig into the Amp SDK today!
+2YX2T7C2GP0U21SH339FBHZJC3UR2CTTH dig.into.the.amp.SDK.today
+
+
+ Yoda said this is not a drill.
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G yoda.said.this.is.not.a.drill
+ Yoda said, a drill this is not.
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G yoda.said.a.drill.this.is.not
+ Yoda said, a drill this is not!
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G yoda.said.a.drill.this.is.not
+ a drill this is not, Yoda said!
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G a.drill.this.is.not.yoda.said
+ said a drill, this is not Yoda.
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G said.a.drill.this.is.not.yoda
+ said a drill, is this not Yoda?
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G said.a.drill.is.this.not.yoda
+ said a drill: Is this not Yoda?
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G said.a.drill.is.this.not.yoda
+ Said a drill,: Is this not Yoda??
+2HKM9422MHYS0Z36YM9BH9J48W7Q0YS8G said.a.drill.is.this.not.yoda
+
+
+ Dots are the canonical way, ya know. after a dozen words, 24 bytes is 2^192!
+732E17Y29S949QPXEXEF6Y9HPKHPGSTQZ dots.are.the.canonical.way.ya.know.after.a.dozen.words.24.bytes.is.2-192
+ Ya know, dots are the canonical way. after a dozen words, 24 bytes is 2^192!
+732E17Y29S949QPXEXEF6Y9HPKHPGSTQZ ya.know.dots.are.the.canonical.way.after.a.dozen.words.24.bytes.is.2-192
+
+
+ The 24-byte tag.ID you see to the left is 2^192 wide (in base 32). For reference, a Bitcoin address is 20 bytes.
+BY2ZN562PFNTBRS7FR3JC657JZYRF06XM the.24-byte.tag.ID.you.see.to.the.left.is.2-192.wide.(in.base.32).for.reference.a.bitcoin.address.is.20.bytes
+
+ Base16 of the ID above (8kj00c8gw8406tugx9bx417whqj3y0qkg) is 160 bits wide. The leading 32 bits are part of a "minting" when a tag is made decidedly private.
+BJ897FM9MU23Y9FFKY5E4PWDG2RJ08M5W base16.of.the.ID.above.(8kj00c8gw8406tugx9bx417whqj3y0qkg).is.160.bits.wide.the.leading.32.bits.are.part.of.a."minting".when.a.tag.is.made.decidedly.private
+
+ The number of possible hashes for a string of 10 words randomly chosen from the worlds dictionaries well over a million words. Even with the English dictionary's 200,000 words, there are 10^50 (2^160) outputs.
+DY3HHE06BYH5C53YP9KC8R1N6K3Q9RN0X the.number.of.possible.hashes.for.a.string.of.10.words.randomly.chosen.from.the.worlds.dictionaries.well.over.a.million.words.even.with.the.english.dictionary's.200.000.words.there.are.10-50.(2-160).outputs
+
+
+ TODO: go get github.com/alecthomas/participle/v2 -- for tags.Parse() implementation?
+337G3KTDQKUX4EN253JKK8QGWFEKER7Q7 TODO.go.get.github.com-alecthomas-participle-v2-for.tags.parse().implementation
+
diff --git a/stdlib/tag/gold_test.go b/stdlib/tag/gold_test.go
new file mode 100644
index 0000000..4a7eb6c
--- /dev/null
+++ b/stdlib/tag/gold_test.go
@@ -0,0 +1,82 @@
+package tag_test
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "path"
+ "strings"
+ "testing"
+
+ "github.com/art-media-platform/amp.SDK/stdlib/tag"
+)
+
+var gTest *testing.T
+
+func TestGold(t *testing.T) {
+ err := os.Chdir("./")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ scriptDir := "gold/"
+ files, err := os.ReadDir(scriptDir)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ for _, fi := range files {
+ itemName := fi.Name()
+ if itemName == "" || fi.IsDir() || itemName[0] == '.' {
+ continue
+ }
+ if !strings.HasSuffix(itemName, ".in.txt") {
+ continue
+ }
+
+ outName := itemName[:len(itemName)-7] + ".out.txt"
+ processTags(
+ path.Join(scriptDir, itemName),
+ path.Join(scriptDir, outName),
+ )
+ }
+}
+
+func echoLine(out *strings.Builder, line string) tag.ID {
+ billet := tag.Expr{}.With(line)
+ if billet.ID.IsSet() {
+ fmt.Fprintf(out, "%33s ", "")
+ out.WriteString(line)
+ out.WriteByte('\n')
+ fmt.Fprintf(out, "%33v %s", billet.ID.Base32(), billet.Canonic)
+ }
+ out.WriteByte('\n')
+ return billet.ID
+}
+
+func processTags(pathIn, pathOut string) {
+ fileOut, err := os.Create(pathOut)
+ if err != nil {
+ gTest.Fatal(err)
+ }
+ defer fileOut.Close()
+ fileIn, err := os.ReadFile(pathIn)
+ if err != nil {
+ gTest.Fatal(err)
+ }
+
+ b := strings.Builder{}
+
+ {
+ echoLine(&b, tag.PackageTags+" . ✙ בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ ✙ .")
+ fileOut.Write([]byte(b.String()))
+ }
+
+ for _, line := range strings.Split(string(fileIn), "\n") {
+ b.Reset()
+ echoLine(&b, line)
+ if _, err := fileOut.Write([]byte(b.String())); err != nil {
+ gTest.Fatal(err)
+ }
+ }
+}
diff --git a/stdlib/tag/tag.go b/stdlib/tag/tag.go
index 00af478..8af86d0 100644
--- a/stdlib/tag/tag.go
+++ b/stdlib/tag/tag.go
@@ -1,6 +1,7 @@
package tag
import (
+ "bytes"
"crypto/sha1"
"encoding/binary"
"encoding/hex"
@@ -12,10 +13,8 @@ import (
)
var (
- // sTagSeparator expresses the delimiters that separate tag literals in a tag.Spec string -- period, comma, colon, slash, backslash, plus, and whitespace
- //
- // By convention, the suggested separator is a period since it helps visually identify a tag, is compatible with a domain name, and is a common scoping character.
- sTagSeparator = regexp.MustCompile(TagDelimiters)
+ sWithDelimiters = regexp.MustCompile(WithDelimiters) // regex for tag processing
+ sThenDelimiters = regexp.MustCompile(ThenDelimiters) // regex for tag processing
)
// Genesis returns a tag.ID that denotes an edit lineage root based on a given seed.
@@ -45,8 +44,14 @@ func (predecessor ID) FormEditID(seed ID) ID {
}
const (
- CanonicWithRune = '.'
- CanonicHideRune = '~'
+
+ // The "with" delimiter can be thought of as ADD or SUM and combines two terms in a commutative way like addition.
+ // A '.' by convention helps visually identify an tag string, it's compatible with domain names, and is already a familiar scoping character.
+ CanonicWith = "."
+ CanonicWithChar = byte('.')
+
+ CanonicThen = "-"
+ CanonicThenChar = byte('-')
)
func (id ID) AppendAsOctals(enc []OctalDigit) []OctalDigit {
@@ -83,72 +88,106 @@ func (id ID) FormAsciiBadge() string {
return string(str)
}
-/*
-func (spec Spec) CanonicString() string {
- if spec.Canonic == "" {
- b := strings.Builder{}
- for _, tag := range spec.Tags {
- if b.Len() > 0 {
- b.WriteRune(CanonicWithRune)
- }
- b.WriteString(tag.Token)
- }
- spec.Canonic = b.String()
- }
- return spec.Canonic
-}
-*/
-
// LeafTags splits the tag spec the given number of tags for the right.
// E.g. LeafTags(2) on "a.b.c.d.ee" yields ("a.b.c", "d.ee")
-func (spec Spec) LeafTags(n int) (string, string) {
+func (expr Expr) LeafTags(n int) (string, string) {
if n <= 0 {
- return spec.Canonic, ""
+ return expr.Canonic, ""
}
- expr := spec.Canonic
- R := len(expr)
+ canonic := expr.Canonic
+ R := len(canonic)
for p := R - 1; p >= 0; p-- {
- switch expr[p] {
- case CanonicHideRune, CanonicWithRune:
+ switch c := canonic[p]; c {
+ case CanonicThenChar, CanonicWithChar:
n--
if n <= 0 {
- return expr[:p], expr[p+1:]
+ prefix := canonic[:p]
+ if c == CanonicWithChar {
+ p++ // omit canonic with operator
+ }
+ return prefix, canonic[p:]
}
}
}
- return "", expr
+ return "", canonic
}
-// A tag.Spec produces a tag.ID such that each tag.ID is unique and is independent of its component tag literals.
+// A tag.Expr produces a tag.ID such that each tag.ID is unique and is independent of its component tag literals.
//
// e.g. "a.b.cc" == "b.a.cc" == "a.cc.b" != "a.cC.b"
-func (spec Spec) With(subTags string) Spec {
- newSpec := Spec{
- ID: spec.ID,
- Canonic: spec.Canonic,
- }
+func (expr Expr) With(tagExpr string) Expr {
+
+ // Cleanup into two operators: With and Then (commutative and non-commutative summation)
+ tagExpr = sWithDelimiters.ReplaceAllString(tagExpr, CanonicWith)
+ tagExpr = sThenDelimiters.ReplaceAllString(tagExpr, CanonicThen)
+ terms := []byte(tagExpr)
+ termsLower := bytes.ToLower(terms)
+ termsUpper := bytes.ToUpper(terms)
+
+ body := make([]byte, 0, len(expr.Canonic)+len(terms))
+ body = append(body, []byte(expr.Canonic)...)
+
+ exprID := expr.ID
+
+ N := len(terms)
+ for i := 0; i < N; {
+ op := CanonicWithChar
+
+ // extract operator
+ for ; i < N; i++ {
+ c := terms[i]
+ if c == CanonicThenChar {
+ op = c
+ } else if c != CanonicWithChar {
+ break
+ }
+ }
- canonic := make([]byte, 0, len(spec.Canonic)+len(subTags))
- canonic = append(canonic, spec.Canonic...)
- tags := sTagSeparator.Split(subTags, 37)
- if len(tags) > 0 {
- for _, ti := range tags {
- if ti == "" { // empty tokens are no-ops
- continue
+ // find end of tag literal
+ start := i
+ lowerCount := 0
+ for ; i < N; i++ {
+ c := terms[i]
+ if c == CanonicWithChar || c == CanonicThenChar {
+ break
}
- if len(canonic) > 0 {
- canonic = append(canonic, CanonicWithRune)
+ if c == termsLower[i] && c != termsUpper[i] {
+ lowerCount++
}
- canonic = append(canonic, []byte(ti)...)
- newSpec.ID = newSpec.ID.WithLiteral([]byte(ti))
}
- newSpec.Canonic = string(canonic)
- } else {
- newSpec.Canonic = spec.Canonic
+ if i == start {
+ continue // skip empty terms
+ }
+
+ // lower-case is canonic unless literal is a single character or ALL upper-case
+ termLen := i - start
+ var term []byte
+ if termLen == 1 || lowerCount > 0 {
+ term = termsLower[start:i]
+ } else {
+ term = terms[start:i]
+ }
+
+ termID := FromLiteral(term)
+ switch op {
+ case CanonicWithChar:
+ exprID = exprID.With(termID)
+ case CanonicThenChar:
+ exprID = exprID.Then(termID)
+ }
+
+ // {tag_operator}{tag_literal}...
+ if len(body) > 0 || op != CanonicWithChar {
+ body = append(body, op)
+ }
+ body = append(body, term...)
}
- return newSpec
+ return Expr{
+ ID: exprID,
+ Canonic: string(body),
+ }
}
const (
@@ -170,9 +209,9 @@ func FromLiteral(tagLiteral []byte) ID {
}
}
-func FromString(unclean string) ID {
- tagLiteral := sTagSeparator.ReplaceAll([]byte(unclean), nil)
- return FromLiteral(tagLiteral)
+func FromExpr(tagsExpr string) ID {
+ spec := Expr{}.With(tagsExpr)
+ return spec.ID
}
func FromToken(literal string) ID {
@@ -253,6 +292,10 @@ func (id ID) Then(other ID) ID {
}
}
+func (id ID) WithExpr(expr string) ID {
+ return id.With(FromExpr(expr))
+}
+
func (id ID) WithToken(tagToken string) ID {
return id.WithLiteral([]byte(tagToken))
}
diff --git a/stdlib/tag/tag_test.go b/stdlib/tag/tag_test.go
index d960af8..fc613c1 100644
--- a/stdlib/tag/tag_test.go
+++ b/stdlib/tag/tag_test.go
@@ -2,41 +2,57 @@ package tag_test
import (
"fmt"
+ "math/rand/v2"
+ "strings"
"testing"
"github.com/art-media-platform/amp.SDK/stdlib/tag"
)
func TestTag(t *testing.T) {
- amp_tags := tag.Spec{}.With("..amp+.app.")
- if amp_tags.ID != tag.FromString(".amp...").WithToken("app") {
+ amp_tags := tag.Expr{}.With("..amp+.app.")
+ if amp_tags.ID != tag.FromExpr(".amp...").WithToken("app") {
t.Fatalf("FormSpec.ID failed: %v", amp_tags.ID)
}
- spec := amp_tags.With("some-tag+thing")
- if spec.Canonic != "amp.app.some-tag.thing" {
+ expr := amp_tags.With("some-tag+thing")
+ if expr.Canonic != "amp.app.some-tag.thing" {
t.Errorf("FormSpec failed")
}
- if spec.ID != amp_tags.ID.WithToken("some-tag").WithToken("thing") {
- t.Fatalf("FormSpec.ID failed: %v", spec.ID)
+ if expr.ID != amp_tags.ID.WithExpr("some-tag").WithToken("thing") {
+ t.Fatalf("FormSpec.ID failed: %v", expr.ID)
}
- if base32 := spec.ID.Base32(); base32 != "28n1xcwsd1q27g4xus3errv17c4r9ecqx" {
+ if base32 := expr.ID.Base32(); base32 != "MUFKXXG22D3JUMC38V43HD11CVH57DDD" {
t.Fatalf("tag.ID.Base32() failed: %v", base32)
}
- if base16 := spec.ID.Base16(); base16 != "24503d5f30c0d847793bac0db7bec27592e96aedd" {
+ if base16 := expr.ID.Base16(); base16 != "9e9d2ef5e213071d4d6346c83830215ee053b18c" {
t.Fatalf("tag.ID.Base16() failed: %v", base16)
}
- if prefix, suffix := spec.LeafTags(2); prefix != "amp.app" || suffix != "some-tag.thing" {
+ if prefix, suffix := expr.LeafTags(2); prefix != "amp.app.some" || suffix != "-tag.thing" {
t.Errorf("LeafTags failed")
}
- genesisStr := "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ"
- if id := tag.FromToken(genesisStr); id[0] != 0xaf07b523 && id[1] != 0xe28f0f37f843664a && id[2] != 0x2c445b67f2be39a0 {
- t.Fatalf("tag.FromString() failed: %v", id)
+ {
+ genesisStr := "בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ"
+ if id := tag.FromToken(genesisStr); id[0] != 0xaf07b523 && id[1] != 0xe28f0f37f843664a && id[2] != 0x2c445b67f2be39a0 {
+ t.Fatalf("tag.FromExpr() failed: %v", id)
+ }
+ parts := strings.Split(genesisStr, " ")
+ for i := 0; i < 3773; i++ {
+ rand.Shuffle(len(parts), func(i, j int) {
+ parts[i], parts[j] = parts[j], parts[i]
+ })
+ tryExpr := strings.Join(parts, ".")
+ tryID := tag.Expr{}.With(tryExpr).ID
+ if tryID[0] != 0x2f4aa1bc0 && tryID[1] != 0xa743a23a89605f6a && tryID[2] != 0xcfec4cf239b7d3fa {
+ t.Fatalf("tag literals commutation test failed: %v", tryID)
+ }
+ }
}
+
tid := tag.ID{0x3, 0x7777777777777777, 0x123456789abcdef0}
- if tid.Base32Suffix() != "g2ectrrh" {
+ if tid.Base32Suffix() != "G2ECTRRH" {
t.Errorf("tag.ID.Base32Suffix() failed")
}
- if tid.Base32() != "vrfxvrfxvrfxvj4e2qg2ectrrh" {
+ if tid.Base32() != "VRFXVRFXVRFXVJ4E2QG2ECTRRH" {
t.Errorf("tag.ID.Base32() failed: %v", tid.Base32())
}
if b16 := tid.Base16(); b16 != "37777777777777777123456789abcdef0" {
@@ -45,9 +61,6 @@ func TestTag(t *testing.T) {
if tid.Base16Suffix() != "abcdef0" {
t.Errorf("tag.ID.Base16Suffix() failed")
}
-
- //fmt.Print(tid.FormAsciiBadge())
-
}
func TestTagEncodings(t *testing.T) {