Skip to main content

triblespace_core/blob/encodings/
longstring.rs

1use crate::inline::Encodes;
2use crate::blob::Blob;
3use crate::blob::BlobEncoding;
4use crate::blob::TryFromBlob;
5use crate::id::ExclusiveId;
6use crate::id::Id;
7use crate::id_hex;
8use crate::macros::entity;
9use crate::metadata;
10use crate::metadata::MetaDescribe;
11use crate::trible::Fragment;
12
13use anybytes::view::ViewError;
14use anybytes::View;
15
16/// Arbitrary-length UTF-8 text stored as a blob.
17///
18/// Use for text that does not fit in the 32-byte [`ShortString`](crate::inline::encodings::shortstring::ShortString)
19/// value boundary — documents, prompts, JSON payloads, logs, etc.
20/// Reference it from tribles via a [`Handle<LongString>`](crate::inline::encodings::hash::Handle).
21pub struct LongString {}
22
23impl BlobEncoding for LongString {}
24
25impl MetaDescribe for LongString {
26    fn describe() -> Fragment {
27        let id: Id = id_hex!("8B173C65B7DB601A11E8A190BD774A79");
28        entity! {
29            ExclusiveId::force_ref(&id) @
30                metadata::name: "longstring",
31                metadata::description: "Arbitrary-length UTF-8 text stored as a blob. This is the default choice for any textual payload that does not fit in 32 bytes, such as documents, prompts, JSON, or logs.\n\nUse ShortString when you need a fixed-width value embedded directly in tribles, want to derive attributes from the bytes, or need predictable ordering inside value indices. LongString is for payloads where size can vary or exceed the value boundary.",
32                metadata::tag: metadata::KIND_BLOB_ENCODING,
33        }
34    }
35}
36
37impl TryFromBlob<LongString> for View<str> {
38    type Error = ViewError;
39
40    fn try_from_blob(b: Blob<LongString>) -> Result<Self, Self::Error> {
41        b.bytes.view()
42    }
43}
44
45impl Encodes<View<str>> for LongString
46where crate::inline::encodings::hash::Handle<LongString>: crate::inline::InlineEncoding,
47{
48    type Output = Blob<LongString>;
49    fn encode(source: View<str>) -> Blob<LongString> {
50        Blob::new(source.bytes())
51    }
52}
53
54impl Encodes<&'static str> for LongString
55where crate::inline::encodings::hash::Handle<LongString>: crate::inline::InlineEncoding,
56{
57    type Output = Blob<LongString>;
58    fn encode(source: &'static str) -> Blob<LongString> {
59        Blob::new(source.into())
60    }
61}
62
63impl Encodes<String> for LongString
64where crate::inline::encodings::hash::Handle<LongString>: crate::inline::InlineEncoding,
65{
66    type Output = Blob<LongString>;
67    fn encode(source: String) -> Blob<LongString> {
68        Blob::new(source.into())
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use anybytes::Bytes;
75    use anybytes::View;
76
77    use crate::blob::encodings::longstring::LongString;
78    use crate::blob::IntoBlob;
79    
80    use crate::inline::encodings::hash::Handle;
81    use crate::inline::Inline;
82
83    #[test]
84    fn string_handle() {
85        let s: View<str> = Bytes::from(String::from("hello world!")).view().unwrap();
86        let h: Inline<Handle<LongString>> = s.clone().to_blob().get_handle();
87        let h2: Inline<Handle<LongString>> = s.clone().to_blob().get_handle();
88
89        assert!(h == h2);
90    }
91}