SpiseMisu.Apache.Thrift.Compact 0.11.5

dotnet add package SpiseMisu.Apache.Thrift.Compact --version 0.11.5
                    
NuGet\Install-Package SpiseMisu.Apache.Thrift.Compact -Version 0.11.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SpiseMisu.Apache.Thrift.Compact" Version="0.11.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SpiseMisu.Apache.Thrift.Compact" Version="0.11.5" />
                    
Directory.Packages.props
<PackageReference Include="SpiseMisu.Apache.Thrift.Compact" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SpiseMisu.Apache.Thrift.Compact --version 0.11.5
                    
#r "nuget: SpiseMisu.Apache.Thrift.Compact, 0.11.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SpiseMisu.Apache.Thrift.Compact@0.11.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SpiseMisu.Apache.Thrift.Compact&version=0.11.5
                    
Install as a Cake Addin
#tool nuget:?package=SpiseMisu.Apache.Thrift.Compact&version=0.11.5
                    
Install as a Cake Tool

SpiseMisu.Apache.Thrift.Compact

A .NET (core) encoder/decoder for the Apache Thrift Compact protocol.

Specs

THRIFT-110 > A more compact format

message               => protocol-id version-and-type seq-id method-name struct-encoding 

protocol-id           => 0x82
version-and-type      => (5-bit version identifier) (3-bit type identifier)
seq-id                => varint
method-name           => varint (N-byte string)
struct-encoding       => field_list stop

field_list            => field field_list
                       | field
field                 => type-and-id value

type-and-id           => field-id-delta type-header
                       | 0 type-header zigzag-varint

field-id-delta        => (4-bit offset from preceding field id, 1-15)

type-header           => boolean-true
                       | boolean-false
                       | byte-type-header
                       | i16-type-header
                       | i32-type-header
                       | i64-type-header
                       | double-type-header
                       | string-type-header
                       | binary-type-header
                       | list-type-header
                       | set-type-header
                       | map-type-header
                       | struct-type-header
                       | extended-type-header

value                 => boolean-true
                       | boolean-false
                       | byte
                       | i16
                       | i32
                       | i64
                       | double
                       | string
                       | binary
                       | list
                       | set
                       | map
                       | struct
                       
stop                  => 0x0
boolean-true          => 0x1
boolean-false         => 0x2
byte-type-header      => 0x3
i16-type-header       => 0x4
i32-type-header       => 0x5
i64-type-header       => 0x6
double-type-header    => 0x7
binary-type-header    => 0x8
string-type-header    => binary-type-header
list-type-header      => 0x9
set-type-header       => 0xA
map-type-header       => 0xB
struct-type-header    => 0xC
extended-type-header  => 0xF

byte                  => (1-byte value)

i16                   => zigzag-varint
i32                   => zigzag-varint
i64                   => zigzag-varint

double                => (8-byte double)

binary                => varint(size) (bytes)
string                => (utf-8 encoded) binary

list                  => short-list
                       | long-list
short-list            => (4-bit size 0-14) (element)type-header
long-list             => 0xf type-header varint(size - 15)
set                   => list
list-body             => value list-body
                       | value

map                   => varint (key)type-header (value)type-header key-value-pair-list
                       | 0
key-value-pair-list   => key-value-pair key-value-pair-list
                       | key-value-pair
key-value-pair        => (key)value (value)value

Source: https://issues.apache.org/jira/secure/attachment/12399869/compact-proto-spec-2.txt

and

Source: https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md

Project structure

├── SpiseMisu.Apache.Thrift.Compact
│   ├── SpiseMisu.Apache.Thrift.Compact.fsproj
│   └── compact.fs
├── SpiseMisu.Apache.Thrift.Compact.Tests
│   ├── SpiseMisu.Apache.Thrift.Compact.Tests.fsproj
│   ├── program.fs
│   └── tests.fs
├── demo
│   └── couchdb.fsx
├── imgs
│   ├── licenses
│   └── nuget
├── SpiseMisu.Apache.Thrift.Compact.sln
├── global.json
├── license.txt
├── license_cil-bytecode_agpl-3.0-only.txt
├── license_knowhow_cc-by-nc-nd-40.txt
└── readme.md

Demo

#!/usr/bin/env -S dotnet fsi --langversion:10.0 --optimize --warnaserror+:25,26 --nowarn:9,42,60,464

//#I @"../SpiseMisu.Apache.Thrift.Compact/bin/Release/net10.0/"
//#r @"SpiseMisu.Apache.Thrift.Compact.dll"

#r "nuget: SpiseMisu.Apache.Thrift.Compact, 00.11.05"

#time "on"

open System

open SpiseMisu.Apache.Thrift
open SpiseMisu.Apache.Thrift.Compact

[<RequireQualifiedAccess>]
module Hex =
  
  open System.Numerics (* #INumberBase<'a> *)
  
  let inline show pad (n:#INumberBase<'a>) =
    let tmp =
      let cs =
        (int64 n).ToString "X2"
        |> Seq.toArray
        |> Array.rev
      cs[0 .. pad - 1]
      |> Array.rev
      |> Array.map string
      |> Array.fold (+) String.Empty
    tmp.PadLeft(pad, '0')

let pprintBytes (bs:byte[]) =
  bs
  |> Array.chunkBySize 16
  |> Array.map (
    Array.map (Hex.show 2)
    >> Array.reduce (sprintf "%s %s")
  )

(* Apache CouchDB Thrift protocol (compact) readme and test cases:
   - https://github.com/apache/couchdb-thrift-protocol/blob/main/README.md
   - https://github.com/apache/couchdb-thrift-protocol/blob/main/test/
*)

let msgSam : Message =
  struct
    ( protocolId
    , Message.Type.Call
    , 0
    , "foo"B
    , [| struct
           ( 1s
           , Bool true 
           )
         struct
           ( 2s
           , I08 -1y
           )
      |]
    )

let bseSam =
  [| 0x82uy; 0x21uy; 0x00uy; 0x03uy; 0x66uy; 0x6Fuy; 0x6Fuy; 0x11uy;
     0x13uy; 0xFFuy; 0x00uy;
  |]

let msgTC0 : Message =
  struct
    ( protocolId
    , Message.Type.Call
    , 1_000
    , "foo"B
    , [| struct
           ( 1s
           , Double 123.456
           )
      |]
    )

let bseTC0 =
  [| 0x82uy; 0x21uy; 0xE8uy; 0x07uy; 0x03uy; 0x66uy; 0x6Fuy; 0x6Fuy;
     0x17uy; 0x77uy; 0xBEuy; 0x9Fuy; 0x1Auy; 0x2Fuy; 0xDDuy; 0x5Euy;
     0x40uy; 0x00uy;
  |]

let msgTC1 : Message =
  struct
    ( protocolId
    , Message.Type.Oneway
    , 1
    , "emitBatch"B
    , [| struct
           ( 1s
           , Struct
               [| struct
                    ( 1s
                    , Struct
                        [| struct
                             ( 1s
                             , Binary "foo_service"B
                             )
                           struct
                             ( 2s
                             , Compact.List
                                 struct
                                   ( Header.Element.Struct
                                   , [| Struct
                                          [| struct
                                               ( 1s
                                               , Binary "jaeger.version"B
                                               )
                                             struct
                                               ( 2s
                                               , I32 0
                                               )
                                             struct
                                               ( 3s
                                               , Binary "Go-2.9.0"B
                                               )
                                          |];
                                        Struct
                                          [| struct
                                               ( 1s
                                               , Binary "hostname"B
                                               )
                                             struct
                                               ( 2s
                                               , I32 0
                                               )
                                             struct
                                               ( 3s
                                               , Binary "ubu"B
                                               )
                                          |];
                                        Struct
                                          [| struct
                                               ( 1s
                                               , Binary "ip"B
                                               )
                                             struct
                                               ( 2s
                                               , I32 0
                                               )
                                             struct
                                               ( 3s
                                               , Binary "10.0.2.15"B
                                               )
                                          |]
                                     |]
                                   )
                             )
                        |]
                    )
                  struct
                    ( 2s
                    , Compact.List
                        struct
                          ( Header.Element.Struct
                          , [| Struct
                                 [| struct
                                      ( 1s
                                      , I64 1508322611000000L
                                      )
                                    struct
                                      ( 2s
                                      , I64 0L
                                      )
                                    struct
                                      ( 3s
                                      , I64 789L
                                      )
                                    struct
                                      ( 4s
                                      , I64 0L
                                      )
                                    struct
                                      ( 5s
                                      , Binary "main"B
                                      )
                                    struct
                                      ( 7s
                                      , I32 1
                                      )
                                    struct
                                      ( 8s
                                      , I64 1508322611000000L
                                      )
                                    struct
                                      ( 9s
                                      , I64 123456L
                                      )
                                 |]
                            |]
                          )
                    )
               |]
           )
      |]
    )

let bseTC1 =
  [| 0x82uy; 0x81uy; 0x01uy; 0x09uy; 0x65uy; 0x6Duy; 0x69uy; 0x74uy;
     0x42uy; 0x61uy; 0x74uy; 0x63uy; 0x68uy; 0x1Cuy; 0x1Cuy; 0x18uy;
     0x0Buy; 0x66uy; 0x6Fuy; 0x6Fuy; 0x5Fuy; 0x73uy; 0x65uy; 0x72uy;
     0x76uy; 0x69uy; 0x63uy; 0x65uy; 0x19uy; 0x3Cuy; 0x18uy; 0x0Euy;
     0x6Auy; 0x61uy; 0x65uy; 0x67uy; 0x65uy; 0x72uy; 0x2Euy; 0x76uy;
     0x65uy; 0x72uy; 0x73uy; 0x69uy; 0x6Fuy; 0x6Euy; 0x15uy; 0x00uy;
     0x18uy; 0x08uy; 0x47uy; 0x6Fuy; 0x2Duy; 0x32uy; 0x2Euy; 0x39uy;
     0x2Euy; 0x30uy; 0x00uy; 0x18uy; 0x08uy; 0x68uy; 0x6Fuy; 0x73uy;
     0x74uy; 0x6Euy; 0x61uy; 0x6Duy; 0x65uy; 0x15uy; 0x00uy; 0x18uy;
     0x03uy; 0x75uy; 0x62uy; 0x75uy; 0x00uy; 0x18uy; 0x02uy; 0x69uy;
     0x70uy; 0x15uy; 0x00uy; 0x18uy; 0x09uy; 0x31uy; 0x30uy; 0x2Euy;
     0x30uy; 0x2Euy; 0x32uy; 0x2Euy; 0x31uy; 0x35uy; 0x00uy; 0x00uy;
     0x19uy; 0x1Cuy; 0x16uy; 0x80uy; 0xCBuy; 0xFBuy; 0x96uy; 0xF7uy;
     0xF3uy; 0xADuy; 0x05uy; 0x16uy; 0x00uy; 0x16uy; 0xAAuy; 0x0Cuy;
     0x16uy; 0x00uy; 0x18uy; 0x04uy; 0x6Duy; 0x61uy; 0x69uy; 0x6Euy;
     0x25uy; 0x02uy; 0x16uy; 0x80uy; 0xCBuy; 0xFBuy; 0x96uy; 0xF7uy;
     0xF3uy; 0xADuy; 0x05uy; 0x16uy; 0x80uy; 0x89uy; 0x0Fuy; 0x00uy;
     0x00uy; 0x00uy;
  |]

let _ =

  let _ =
    
    let txt = "### apache/couchdb-thrift-protocol README sample:"
    let msg = msgSam
    let bst = bseSam
    
    let struct(bse, _) = Encode.toBytes   msg
    let struct(dec, _) = Decode.fromBytes bst
    
    printfn "%s" txt
    
    printfn "#### Encoded bytes:"
    printfn "```"
    bst
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    Seq.toArray bse = bst
    |> printfn "#### Encoded message = bytes: %b"
    printfn "```"
    bse
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    dec = msg
    |> printfn "#### Decoded bytes = message: %b"
    printfn "```fsharp"
    printfn "%A" dec
    printfn "```"
    printfn "%s" String.Empty

  let _ =
    
    let txt = "### apache/couchdb-thrift-protocol Test-case 0:"
    let msg = msgTC0
    let bst = bseTC0
    
    let struct(bse, _) = Encode.toBytes   msg
    let struct(dec, _) = Decode.fromBytes bst
    
    printfn "%s" txt
    
    printfn "#### Encoded bytes:"
    printfn "```"
    bst
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    Seq.toArray bse = bst
    |> printfn "#### Encoded message = bytes: %b"
    printfn "```"
    bse
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    dec = msg
    |> printfn "#### Decoded bytes = message: %b"
    printfn "```fsharp"
    printfn "%A" dec
    printfn "```"
    printfn "%s" String.Empty

  let _ =
    
    let txt = "### apache/couchdb-thrift-protocol Test-case 1:"
    let msg = msgTC1
    let bst = bseTC1
    
    let struct(bse, _) = Encode.toBytes   msg
    let struct(dec, _) = Decode.fromBytes bst
    
    printfn "%s" txt
    
    printfn "#### Encoded bytes:"
    printfn "```"
    bst
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    Seq.toArray bse = bst
    |> printfn "#### Encoded message = bytes: %b"
    printfn "```"
    bse
    |> Seq.toArray
    |> pprintBytes
    |> Array.iter (printfn "%s")
    printfn "```"
    printfn "%s" String.Empty
    
    dec = msg
    |> printfn "#### Decoded bytes = message: %b"
    printfn "```fsharp"
    printfn "%A" dec
    printfn "```"
    printfn "%s" String.Empty

  00

and

apache/couchdb-thrift-protocol README sample:

Encoded bytes:
82 21 00 03 66 6F 6F 11 13 FF 00
Encoded message = bytes: true
82 21 00 03 66 6F 6F 11 13 FF 00
Decoded bytes = message: true
struct (130uy, Call, 0, [|102uy; 111uy; 111uy|],
        [|struct (1s, Bool true); struct (2s, I08 -1y)|])

apache/couchdb-thrift-protocol Test-case 0:

Encoded bytes:
82 21 E8 07 03 66 6F 6F 17 77 BE 9F 1A 2F DD 5E
40 00
Encoded message = bytes: true
82 21 E8 07 03 66 6F 6F 17 77 BE 9F 1A 2F DD 5E
40 00
Decoded bytes = message: true
struct (130uy, Call, 1000, [|102uy; 111uy; 111uy|],
        [|struct (1s, Double 123.456)|])

apache/couchdb-thrift-protocol Test-case 1:

Encoded bytes:
82 81 01 09 65 6D 69 74 42 61 74 63 68 1C 1C 18
0B 66 6F 6F 5F 73 65 72 76 69 63 65 19 3C 18 0E
6A 61 65 67 65 72 2E 76 65 72 73 69 6F 6E 15 00
18 08 47 6F 2D 32 2E 39 2E 30 00 18 08 68 6F 73
74 6E 61 6D 65 15 00 18 03 75 62 75 00 18 02 69
70 15 00 18 09 31 30 2E 30 2E 32 2E 31 35 00 00
19 1C 16 80 CB FB 96 F7 F3 AD 05 16 00 16 AA 0C
16 00 18 04 6D 61 69 6E 25 02 16 80 CB FB 96 F7
F3 AD 05 16 80 89 0F 00 00 00
Encoded message = bytes: true
82 81 01 09 65 6D 69 74 42 61 74 63 68 1C 1C 18
0B 66 6F 6F 5F 73 65 72 76 69 63 65 19 3C 18 0E
6A 61 65 67 65 72 2E 76 65 72 73 69 6F 6E 15 00
18 08 47 6F 2D 32 2E 39 2E 30 00 18 08 68 6F 73
74 6E 61 6D 65 15 00 18 03 75 62 75 00 18 02 69
70 15 00 18 09 31 30 2E 30 2E 32 2E 31 35 00 00
19 1C 16 80 CB FB 96 F7 F3 AD 05 16 00 16 AA 0C
16 00 18 04 6D 61 69 6E 25 02 16 80 CB FB 96 F7
F3 AD 05 16 80 89 0F 00 00 00
Decoded bytes = message: true
struct (130uy, Oneway, 1,
        [|101uy; 109uy; 105uy; 116uy; 66uy; 97uy; 116uy; 99uy; 104uy|],
        [|struct (1s,
                  Struct
                    [|struct (1s,
                              Struct
                                [|struct (1s,
                                          Binary
                                            [|102uy; 111uy; 111uy; 95uy; 115uy;
                                              101uy; 114uy; 118uy; 105uy; 99uy;
                                              101uy|]);
                                  struct (2s,
                                          List
                                            struct (Struct,
                                                    [|Struct
                                                        [|struct (1s,
                                                                  Binary
                                                                    [|106uy;
                                                                      97uy;
                                                                      101uy;
                                                                      103uy;
                                                                      101uy;
                                                                      114uy;
                                                                      46uy;
                                                                      118uy;
                                                                      101uy;
                                                                      114uy;
                                                                      115uy;
                                                                      105uy;
                                                                      111uy;
                                                                      110uy|]);
                                                          struct (2s, I32 0);
                                                          struct (3s,
                                                                  Binary
                                                                    [|71uy;
                                                                      111uy;
                                                                      45uy; 50uy;
                                                                      46uy; 57uy;
                                                                      46uy; 48uy|])|];
                                                      Struct
                                                        [|struct (1s,
                                                                  Binary
                                                                    [|104uy;
                                                                      111uy;
                                                                      115uy;
                                                                      116uy;
                                                                      110uy;
                                                                      97uy;
                                                                      109uy;
                                                                      101uy|]);
                                                          struct (2s, I32 0);
                                                          struct (3s,
                                                                  Binary
                                                                    [|117uy;
                                                                      98uy;
                                                                      117uy|])|];
                                                      Struct
                                                        [|struct (1s,
                                                                  Binary
                                                                    [|105uy;
                                                                      112uy|]);
                                                          struct (2s, I32 0);
                                                          struct (3s,
                                                                  Binary
                                                                    [|49uy; 48uy;
                                                                      46uy; 48uy;
                                                                      46uy; 50uy;
                                                                      46uy; 49uy;
                                                                      53uy|])|]|]))|]);
                      struct (2s,
                              List
                                struct (Struct,
                                        [|Struct
                                            [|struct (1s, I64 1508322611000000L);
                                              struct (2s, I64 0L);
                                              struct (3s, I64 789L);
                                              struct (4s, I64 0L);
                                              struct (5s,
                                                      Binary
                                                        [|109uy; 97uy; 105uy;
                                                          110uy|]);
                                              struct (7s, I32 1);
                                              struct (8s, I64 1508322611000000L);
                                              struct (9s, I64 123456L)|]|]))|])|])

Licenses

Source code in this repository is ONLY covered by a Server Side Public License, v 1 while the rest (knowhow, text, media, …), is covered by the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International license.

Figure: CC BY-NC-ND 4.0

However, as it's not permitted to deploy a nuget package with non OSI nor FSF licenses. The CIL-bytecode content of the nuget package is therefore dual-licensed under the GNU Affero General Public License v3.0 only and the rest (knowhow, text, media, …), is covered by the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International license.

For more info on compatible nuget packages licenses, see SPDX License List.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.11.5 422 11/18/2025
0.11.4 204 11/6/2025
0.11.3 193 10/29/2025
0.11.2 190 10/29/2025
0.11.1 192 10/29/2025
0.11.0 194 10/29/2025