/ duper_uniffi / dotnet / duper.cs
duper.cs
   1  // <auto-generated>
   2  //     This file was generated by uniffi-bindgen-cs v0.10.0+v0.29.4
   3  //     See https://github.com/NordSecurity/uniffi-bindgen-cs for more information.
   4  // </auto-generated>
   5  
   6  #nullable enable
   7  
   8  using System;
   9  using System.Collections.Generic;
  10  using System.IO;
  11  using System.Linq;
  12  using System.Runtime.InteropServices;
  13  
  14  namespace Duper.Ffi;
  15  
  16  // This is a helper for safely working with byte buffers returned from the Rust code.
  17  // A rust-owned buffer is represented by its capacity, its current length, and a
  18  // pointer to the underlying data.
  19  
  20  [StructLayout(LayoutKind.Sequential)]
  21  internal struct RustBuffer
  22  {
  23      public ulong capacity;
  24      public ulong len;
  25      public IntPtr data;
  26  
  27      public static RustBuffer Alloc(int size)
  28      {
  29          return _UniffiHelpers.RustCall(
  30              (ref UniffiRustCallStatus status) =>
  31              {
  32                  var buffer = _UniFFILib.ffi_duper_uniffi_rustbuffer_alloc(
  33                      Convert.ToUInt64(size),
  34                      ref status
  35                  );
  36                  if (buffer.data == IntPtr.Zero)
  37                  {
  38                      throw new AllocationException(
  39                          $"RustBuffer.Alloc() returned null data pointer (size={size})"
  40                      );
  41                  }
  42                  return buffer;
  43              }
  44          );
  45      }
  46  
  47      public static void Free(RustBuffer buffer)
  48      {
  49          _UniffiHelpers.RustCall(
  50              (ref UniffiRustCallStatus status) =>
  51              {
  52                  _UniFFILib.ffi_duper_uniffi_rustbuffer_free(buffer, ref status);
  53              }
  54          );
  55      }
  56  
  57      public static BigEndianStream MemoryStream(IntPtr data, long length)
  58      {
  59          unsafe
  60          {
  61              return new BigEndianStream(new UnmanagedMemoryStream((byte*)data.ToPointer(), length));
  62          }
  63      }
  64  
  65      public BigEndianStream AsStream()
  66      {
  67          unsafe
  68          {
  69              return new BigEndianStream(
  70                  new UnmanagedMemoryStream((byte*)data.ToPointer(), Convert.ToInt64(len))
  71              );
  72          }
  73      }
  74  
  75      public BigEndianStream AsWriteableStream()
  76      {
  77          unsafe
  78          {
  79              return new BigEndianStream(
  80                  new UnmanagedMemoryStream(
  81                      (byte*)data.ToPointer(),
  82                      Convert.ToInt64(capacity),
  83                      Convert.ToInt64(capacity),
  84                      FileAccess.Write
  85                  )
  86              );
  87          }
  88      }
  89  }
  90  
  91  // This is a helper for safely passing byte references into the rust code.
  92  // It's not actually used at the moment, because there aren't many things that you
  93  // can take a direct pointer to managed memory, and if we're going to copy something
  94  // then we might as well copy it into a `RustBuffer`. But it's here for API
  95  // completeness.
  96  
  97  [StructLayout(LayoutKind.Sequential)]
  98  internal struct ForeignBytes
  99  {
 100      public int length;
 101      public IntPtr data;
 102  }
 103  
 104  // The FfiConverter interface handles converter types to and from the FFI
 105  //
 106  // All implementing objects should be public to support external types.  When a
 107  // type is external we need to import it's FfiConverter.
 108  internal abstract class FfiConverter<CsType, FfiType>
 109  {
 110      // Convert an FFI type to a C# type
 111      public abstract CsType Lift(FfiType value);
 112  
 113      // Convert C# type to an FFI type
 114      public abstract FfiType Lower(CsType value);
 115  
 116      // Read a C# type from a `ByteBuffer`
 117      public abstract CsType Read(BigEndianStream stream);
 118  
 119      // Calculate bytes to allocate when creating a `RustBuffer`
 120      //
 121      // This must return at least as many bytes as the write() function will
 122      // write. It can return more bytes than needed, for example when writing
 123      // Strings we can't know the exact bytes needed until we the UTF-8
 124      // encoding, so we pessimistically allocate the largest size possible (3
 125      // bytes per codepoint).  Allocating extra bytes is not really a big deal
 126      // because the `RustBuffer` is short-lived.
 127      public abstract int AllocationSize(CsType value);
 128  
 129      // Write a C# type to a `ByteBuffer`
 130      public abstract void Write(CsType value, BigEndianStream stream);
 131  
 132      // Lower a value into a `RustBuffer`
 133      //
 134      // This method lowers a value into a `RustBuffer` rather than the normal
 135      // FfiType.  It's used by the callback interface code.  Callback interface
 136      // returns are always serialized into a `RustBuffer` regardless of their
 137      // normal FFI type.
 138      public RustBuffer LowerIntoRustBuffer(CsType value)
 139      {
 140          var rbuf = RustBuffer.Alloc(AllocationSize(value));
 141          try
 142          {
 143              var stream = rbuf.AsWriteableStream();
 144              Write(value, stream);
 145              rbuf.len = Convert.ToUInt64(stream.Position);
 146              return rbuf;
 147          }
 148          catch
 149          {
 150              RustBuffer.Free(rbuf);
 151              throw;
 152          }
 153      }
 154  
 155      // Lift a value from a `RustBuffer`.
 156      //
 157      // This here mostly because of the symmetry with `lowerIntoRustBuffer()`.
 158      // It's currently only used by the `FfiConverterRustBuffer` class below.
 159      protected CsType LiftFromRustBuffer(RustBuffer rbuf)
 160      {
 161          var stream = rbuf.AsStream();
 162          try
 163          {
 164              var item = Read(stream);
 165              if (stream.HasRemaining())
 166              {
 167                  throw new InternalException(
 168                      "junk remaining in buffer after lifting, something is very wrong!!"
 169                  );
 170              }
 171              return item;
 172          }
 173          finally
 174          {
 175              RustBuffer.Free(rbuf);
 176          }
 177      }
 178  }
 179  
 180  // FfiConverter that uses `RustBuffer` as the FfiType
 181  internal abstract class FfiConverterRustBuffer<CsType> : FfiConverter<CsType, RustBuffer>
 182  {
 183      public override CsType Lift(RustBuffer value)
 184      {
 185          return LiftFromRustBuffer(value);
 186      }
 187  
 188      public override RustBuffer Lower(CsType value)
 189      {
 190          return LowerIntoRustBuffer(value);
 191      }
 192  }
 193  
 194  // A handful of classes and functions to support the generated data structures.
 195  // This would be a good candidate for isolating in its own ffi-support lib.
 196  // Error runtime.
 197  [StructLayout(LayoutKind.Sequential)]
 198  struct UniffiRustCallStatus
 199  {
 200      public sbyte code;
 201      public RustBuffer error_buf;
 202  
 203      public bool IsSuccess()
 204      {
 205          return code == 0;
 206      }
 207  
 208      public bool IsError()
 209      {
 210          return code == 1;
 211      }
 212  
 213      public bool IsPanic()
 214      {
 215          return code == 2;
 216      }
 217  }
 218  
 219  // Base class for all uniffi exceptions
 220  internal class UniffiException : System.Exception
 221  {
 222      public UniffiException()
 223          : base() { }
 224  
 225      public UniffiException(string message)
 226          : base(message) { }
 227  }
 228  
 229  internal class UndeclaredErrorException : UniffiException
 230  {
 231      public UndeclaredErrorException(string message)
 232          : base(message) { }
 233  }
 234  
 235  internal class PanicException : UniffiException
 236  {
 237      public PanicException(string message)
 238          : base(message) { }
 239  }
 240  
 241  internal class AllocationException : UniffiException
 242  {
 243      public AllocationException(string message)
 244          : base(message) { }
 245  }
 246  
 247  internal class InternalException : UniffiException
 248  {
 249      public InternalException(string message)
 250          : base(message) { }
 251  }
 252  
 253  internal class InvalidEnumException : InternalException
 254  {
 255      public InvalidEnumException(string message)
 256          : base(message) { }
 257  }
 258  
 259  internal class UniffiContractVersionException : UniffiException
 260  {
 261      public UniffiContractVersionException(string message)
 262          : base(message) { }
 263  }
 264  
 265  internal class UniffiContractChecksumException : UniffiException
 266  {
 267      public UniffiContractChecksumException(string message)
 268          : base(message) { }
 269  }
 270  
 271  // Each top-level error class has a companion object that can lift the error from the call status's rust buffer
 272  interface CallStatusErrorHandler<E>
 273      where E : System.Exception
 274  {
 275      E Lift(RustBuffer error_buf);
 276  }
 277  
 278  // CallStatusErrorHandler implementation for times when we don't expect a CALL_ERROR
 279  class NullCallStatusErrorHandler : CallStatusErrorHandler<UniffiException>
 280  {
 281      public static NullCallStatusErrorHandler INSTANCE = new NullCallStatusErrorHandler();
 282  
 283      public UniffiException Lift(RustBuffer error_buf)
 284      {
 285          RustBuffer.Free(error_buf);
 286          return new UndeclaredErrorException(
 287              "library has returned an error not declared in UNIFFI interface file"
 288          );
 289      }
 290  }
 291  
 292  // Helpers for calling Rust
 293  // In practice we usually need to be synchronized to call this safely, so it doesn't
 294  // synchronize itself
 295  class _UniffiHelpers
 296  {
 297      public delegate void RustCallAction(ref UniffiRustCallStatus status);
 298      public delegate U RustCallFunc<out U>(ref UniffiRustCallStatus status);
 299  
 300      // Call a rust function that returns a Result<>.  Pass in the Error class companion that corresponds to the Err
 301      public static U RustCallWithError<U, E>(
 302          CallStatusErrorHandler<E> errorHandler,
 303          RustCallFunc<U> callback
 304      )
 305          where E : UniffiException
 306      {
 307          var status = new UniffiRustCallStatus();
 308          var return_value = callback(ref status);
 309          if (status.IsSuccess())
 310          {
 311              return return_value;
 312          }
 313          else if (status.IsError())
 314          {
 315              throw errorHandler.Lift(status.error_buf);
 316          }
 317          else if (status.IsPanic())
 318          {
 319              // when the rust code sees a panic, it tries to construct a rustbuffer
 320              // with the message.  but if that code panics, then it just sends back
 321              // an empty buffer.
 322              if (status.error_buf.len > 0)
 323              {
 324                  throw new PanicException(FfiConverterString.INSTANCE.Lift(status.error_buf));
 325              }
 326              else
 327              {
 328                  throw new PanicException("Rust panic");
 329              }
 330          }
 331          else
 332          {
 333              throw new InternalException($"Unknown rust call status: {status.code}");
 334          }
 335      }
 336  
 337      // Call a rust function that returns a Result<>.  Pass in the Error class companion that corresponds to the Err
 338      public static void RustCallWithError<E>(
 339          CallStatusErrorHandler<E> errorHandler,
 340          RustCallAction callback
 341      )
 342          where E : UniffiException
 343      {
 344          _UniffiHelpers.RustCallWithError(
 345              errorHandler,
 346              (ref UniffiRustCallStatus status) =>
 347              {
 348                  callback(ref status);
 349                  return 0;
 350              }
 351          );
 352      }
 353  
 354      // Call a rust function that returns a plain value
 355      public static U RustCall<U>(RustCallFunc<U> callback)
 356      {
 357          return _UniffiHelpers.RustCallWithError(NullCallStatusErrorHandler.INSTANCE, callback);
 358      }
 359  
 360      // Call a rust function that returns a plain value
 361      public static void RustCall(RustCallAction callback)
 362      {
 363          _UniffiHelpers.RustCall(
 364              (ref UniffiRustCallStatus status) =>
 365              {
 366                  callback(ref status);
 367                  return 0;
 368              }
 369          );
 370      }
 371  }
 372  
 373  static class FFIObjectUtil
 374  {
 375      public static void DisposeAll(params Object?[] list)
 376      {
 377          Dispose(list);
 378      }
 379  
 380      // Dispose is implemented by recursive type inspection at runtime. This is because
 381      // generating correct Dispose calls for recursive complex types, e.g. List<List<int>>
 382      // is quite cumbersome.
 383      private static void Dispose(Object? obj)
 384      {
 385          if (obj == null)
 386          {
 387              return;
 388          }
 389  
 390          if (obj is IDisposable disposable)
 391          {
 392              disposable.Dispose();
 393              return;
 394          }
 395  
 396          var objType = obj.GetType();
 397          var typeCode = Type.GetTypeCode(objType);
 398          if (typeCode != TypeCode.Object)
 399          {
 400              return;
 401          }
 402  
 403          var genericArguments = objType.GetGenericArguments();
 404          if (genericArguments.Length == 0 && !objType.IsArray)
 405          {
 406              return;
 407          }
 408  
 409          if (obj is System.Collections.IDictionary objDictionary)
 410          {
 411              //This extra code tests to not call "Dispose" for a Dictionary<something, double>()
 412              //for all values as "double" and alike doesn't support interface "IDisposable"
 413              var valuesType = objType.GetGenericArguments()[1];
 414              var elementValuesTypeCode = Type.GetTypeCode(valuesType);
 415              if (elementValuesTypeCode != TypeCode.Object)
 416              {
 417                  return;
 418              }
 419              foreach (var value in objDictionary.Values)
 420              {
 421                  Dispose(value);
 422              }
 423          }
 424          else if (obj is System.Collections.IEnumerable listValues)
 425          {
 426              //This extra code tests to not call "Dispose" for a List<int>()
 427              //for all keys as "int" and alike doesn't support interface "IDisposable"
 428              var elementType = objType.IsArray ? objType.GetElementType() : genericArguments[0];
 429              var elementValuesTypeCode = Type.GetTypeCode(elementType);
 430              if (elementValuesTypeCode != TypeCode.Object)
 431              {
 432                  return;
 433              }
 434              foreach (var value in listValues)
 435              {
 436                  Dispose(value);
 437              }
 438          }
 439      }
 440  }
 441  
 442  // Big endian streams are not yet available in dotnet :'(
 443  // https://github.com/dotnet/runtime/issues/26904
 444  
 445  class StreamUnderflowException : System.Exception
 446  {
 447      public StreamUnderflowException() { }
 448  }
 449  
 450  static class BigEndianStreamExtensions
 451  {
 452      public static void WriteInt32(this Stream stream, int value, int bytesToWrite = 4)
 453      {
 454  #if DOTNET_8_0_OR_GREATER
 455          Span<byte> buffer = stackalloc byte[bytesToWrite];
 456  #else
 457          byte[] buffer = new byte[bytesToWrite];
 458  #endif
 459          var posByte = bytesToWrite;
 460          while (posByte != 0)
 461          {
 462              posByte--;
 463              buffer[posByte] = (byte)(value);
 464              value >>= 8;
 465          }
 466  
 467  #if DOTNET_8_0_OR_GREATER
 468          stream.Write(buffer);
 469  #else
 470          stream.Write(buffer, 0, buffer.Length);
 471  #endif
 472      }
 473  
 474      public static void WriteInt64(this Stream stream, long value)
 475      {
 476          int bytesToWrite = 8;
 477  #if DOTNET_8_0_OR_GREATER
 478          Span<byte> buffer = stackalloc byte[bytesToWrite];
 479  #else
 480          byte[] buffer = new byte[bytesToWrite];
 481  #endif
 482          var posByte = bytesToWrite;
 483          while (posByte != 0)
 484          {
 485              posByte--;
 486              buffer[posByte] = (byte)(value);
 487              value >>= 8;
 488          }
 489  
 490  #if DOTNET_8_0_OR_GREATER
 491          stream.Write(buffer);
 492  #else
 493          stream.Write(buffer, 0, buffer.Length);
 494  #endif
 495      }
 496  
 497      public static uint ReadUint32(this Stream stream, int bytesToRead = 4)
 498      {
 499          CheckRemaining(stream, bytesToRead);
 500  #if DOTNET_8_0_OR_GREATER
 501          Span<byte> buffer = stackalloc byte[bytesToRead];
 502          stream.Read(buffer);
 503  #else
 504          byte[] buffer = new byte[bytesToRead];
 505          stream.Read(buffer, 0, bytesToRead);
 506  #endif
 507          uint result = 0;
 508          uint digitMultiplier = 1;
 509          int posByte = bytesToRead;
 510          while (posByte != 0)
 511          {
 512              posByte--;
 513              result |= buffer[posByte] * digitMultiplier;
 514              digitMultiplier <<= 8;
 515          }
 516  
 517          return result;
 518      }
 519  
 520      public static ulong ReadUInt64(this Stream stream)
 521      {
 522          int bytesToRead = 8;
 523          CheckRemaining(stream, bytesToRead);
 524  #if DOTNET_8_0_OR_GREATER
 525          Span<byte> buffer = stackalloc byte[bytesToRead];
 526          stream.Read(buffer);
 527  #else
 528          byte[] buffer = new byte[bytesToRead];
 529          stream.Read(buffer, 0, bytesToRead);
 530  #endif
 531          ulong result = 0;
 532          ulong digitMultiplier = 1;
 533          int posByte = bytesToRead;
 534          while (posByte != 0)
 535          {
 536              posByte--;
 537              result |= buffer[posByte] * digitMultiplier;
 538              digitMultiplier <<= 8;
 539          }
 540  
 541          return result;
 542      }
 543  
 544      public static void CheckRemaining(this Stream stream, int length)
 545      {
 546          if (stream.Length - stream.Position < length)
 547          {
 548              throw new StreamUnderflowException();
 549          }
 550      }
 551  
 552      public static void ForEach<T>(this T[] items, Action<T> action)
 553      {
 554          foreach (var item in items)
 555          {
 556              action(item);
 557          }
 558      }
 559  }
 560  
 561  class BigEndianStream
 562  {
 563      Stream stream;
 564  
 565      public BigEndianStream(Stream stream)
 566      {
 567          this.stream = stream;
 568      }
 569  
 570      public bool HasRemaining()
 571      {
 572          return (stream.Length - Position) > 0;
 573      }
 574  
 575      public long Position
 576      {
 577          get => stream.Position;
 578          set => stream.Position = value;
 579      }
 580  
 581      public void WriteBytes(byte[] buffer)
 582      {
 583  #if DOTNET_8_0_OR_GREATER
 584          stream.Write(buffer);
 585  #else
 586          stream.Write(buffer, 0, buffer.Length);
 587  #endif
 588      }
 589  
 590      public void WriteByte(byte value) => stream.WriteInt32(value, bytesToWrite: 1);
 591  
 592      public void WriteSByte(sbyte value) => stream.WriteInt32(value, bytesToWrite: 1);
 593  
 594      public void WriteUShort(ushort value) => stream.WriteInt32(value, bytesToWrite: 2);
 595  
 596      public void WriteShort(short value) => stream.WriteInt32(value, bytesToWrite: 2);
 597  
 598      public void WriteUInt(uint value) => stream.WriteInt32((int)value);
 599  
 600      public void WriteInt(int value) => stream.WriteInt32(value);
 601  
 602      public void WriteULong(ulong value) => stream.WriteInt64((long)value);
 603  
 604      public void WriteLong(long value) => stream.WriteInt64(value);
 605  
 606      public void WriteFloat(float value)
 607      {
 608          unsafe
 609          {
 610              WriteInt(*((int*)&value));
 611          }
 612      }
 613  
 614      public void WriteDouble(double value) =>
 615          stream.WriteInt64(BitConverter.DoubleToInt64Bits(value));
 616  
 617      public byte[] ReadBytes(int length)
 618      {
 619          stream.CheckRemaining(length);
 620          byte[] result = new byte[length];
 621          stream.Read(result, 0, length);
 622          return result;
 623      }
 624  
 625      public byte ReadByte() => (byte)stream.ReadUint32(bytesToRead: 1);
 626  
 627      public ushort ReadUShort() => (ushort)stream.ReadUint32(bytesToRead: 2);
 628  
 629      public uint ReadUInt() => (uint)stream.ReadUint32(bytesToRead: 4);
 630  
 631      public ulong ReadULong() => stream.ReadUInt64();
 632  
 633      public sbyte ReadSByte() => (sbyte)ReadByte();
 634  
 635      public short ReadShort() => (short)ReadUShort();
 636  
 637      public int ReadInt() => (int)ReadUInt();
 638  
 639      public float ReadFloat()
 640      {
 641          unsafe
 642          {
 643              int value = ReadInt();
 644              return *((float*)&value);
 645          }
 646      }
 647  
 648      public long ReadLong() => (long)ReadULong();
 649  
 650      public double ReadDouble() => BitConverter.Int64BitsToDouble(ReadLong());
 651  }
 652  
 653  // Contains loading, initialization code,
 654  // and the FFI Function declarations in a com.sun.jna.Library.
 655  
 656  // This is an implementation detail that will be called internally by the public API.
 657  static class _UniFFILib
 658  {
 659      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 660      public delegate void UniffiRustFutureContinuationCallback(ulong @data, sbyte @pollResult);
 661  
 662      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 663      public delegate void UniffiForeignFutureFree(ulong @handle);
 664  
 665      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 666      public delegate void UniffiCallbackInterfaceFree(ulong @handle);
 667  
 668      [StructLayout(LayoutKind.Sequential)]
 669      public struct UniffiForeignFuture
 670      {
 671          public ulong @handle;
 672          public IntPtr @free;
 673      }
 674  
 675      [StructLayout(LayoutKind.Sequential)]
 676      public struct UniffiForeignFutureStructU8
 677      {
 678          public byte @returnValue;
 679          public UniffiRustCallStatus @callStatus;
 680      }
 681  
 682      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 683      public delegate void UniffiForeignFutureCompleteU8(
 684          ulong @callbackData,
 685          _UniFFILib.UniffiForeignFutureStructU8 @result
 686      );
 687  
 688      [StructLayout(LayoutKind.Sequential)]
 689      public struct UniffiForeignFutureStructI8
 690      {
 691          public sbyte @returnValue;
 692          public UniffiRustCallStatus @callStatus;
 693      }
 694  
 695      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 696      public delegate void UniffiForeignFutureCompleteI8(
 697          ulong @callbackData,
 698          _UniFFILib.UniffiForeignFutureStructI8 @result
 699      );
 700  
 701      [StructLayout(LayoutKind.Sequential)]
 702      public struct UniffiForeignFutureStructU16
 703      {
 704          public ushort @returnValue;
 705          public UniffiRustCallStatus @callStatus;
 706      }
 707  
 708      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 709      public delegate void UniffiForeignFutureCompleteU16(
 710          ulong @callbackData,
 711          _UniFFILib.UniffiForeignFutureStructU16 @result
 712      );
 713  
 714      [StructLayout(LayoutKind.Sequential)]
 715      public struct UniffiForeignFutureStructI16
 716      {
 717          public short @returnValue;
 718          public UniffiRustCallStatus @callStatus;
 719      }
 720  
 721      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 722      public delegate void UniffiForeignFutureCompleteI16(
 723          ulong @callbackData,
 724          _UniFFILib.UniffiForeignFutureStructI16 @result
 725      );
 726  
 727      [StructLayout(LayoutKind.Sequential)]
 728      public struct UniffiForeignFutureStructU32
 729      {
 730          public uint @returnValue;
 731          public UniffiRustCallStatus @callStatus;
 732      }
 733  
 734      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 735      public delegate void UniffiForeignFutureCompleteU32(
 736          ulong @callbackData,
 737          _UniFFILib.UniffiForeignFutureStructU32 @result
 738      );
 739  
 740      [StructLayout(LayoutKind.Sequential)]
 741      public struct UniffiForeignFutureStructI32
 742      {
 743          public int @returnValue;
 744          public UniffiRustCallStatus @callStatus;
 745      }
 746  
 747      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 748      public delegate void UniffiForeignFutureCompleteI32(
 749          ulong @callbackData,
 750          _UniFFILib.UniffiForeignFutureStructI32 @result
 751      );
 752  
 753      [StructLayout(LayoutKind.Sequential)]
 754      public struct UniffiForeignFutureStructU64
 755      {
 756          public ulong @returnValue;
 757          public UniffiRustCallStatus @callStatus;
 758      }
 759  
 760      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 761      public delegate void UniffiForeignFutureCompleteU64(
 762          ulong @callbackData,
 763          _UniFFILib.UniffiForeignFutureStructU64 @result
 764      );
 765  
 766      [StructLayout(LayoutKind.Sequential)]
 767      public struct UniffiForeignFutureStructI64
 768      {
 769          public long @returnValue;
 770          public UniffiRustCallStatus @callStatus;
 771      }
 772  
 773      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 774      public delegate void UniffiForeignFutureCompleteI64(
 775          ulong @callbackData,
 776          _UniFFILib.UniffiForeignFutureStructI64 @result
 777      );
 778  
 779      [StructLayout(LayoutKind.Sequential)]
 780      public struct UniffiForeignFutureStructF32
 781      {
 782          public float @returnValue;
 783          public UniffiRustCallStatus @callStatus;
 784      }
 785  
 786      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 787      public delegate void UniffiForeignFutureCompleteF32(
 788          ulong @callbackData,
 789          _UniFFILib.UniffiForeignFutureStructF32 @result
 790      );
 791  
 792      [StructLayout(LayoutKind.Sequential)]
 793      public struct UniffiForeignFutureStructF64
 794      {
 795          public double @returnValue;
 796          public UniffiRustCallStatus @callStatus;
 797      }
 798  
 799      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 800      public delegate void UniffiForeignFutureCompleteF64(
 801          ulong @callbackData,
 802          _UniFFILib.UniffiForeignFutureStructF64 @result
 803      );
 804  
 805      [StructLayout(LayoutKind.Sequential)]
 806      public struct UniffiForeignFutureStructPointer
 807      {
 808          public IntPtr @returnValue;
 809          public UniffiRustCallStatus @callStatus;
 810      }
 811  
 812      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 813      public delegate void UniffiForeignFutureCompletePointer(
 814          ulong @callbackData,
 815          _UniFFILib.UniffiForeignFutureStructPointer @result
 816      );
 817  
 818      [StructLayout(LayoutKind.Sequential)]
 819      public struct UniffiForeignFutureStructRustBuffer
 820      {
 821          public RustBuffer @returnValue;
 822          public UniffiRustCallStatus @callStatus;
 823      }
 824  
 825      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 826      public delegate void UniffiForeignFutureCompleteRustBuffer(
 827          ulong @callbackData,
 828          _UniFFILib.UniffiForeignFutureStructRustBuffer @result
 829      );
 830  
 831      [StructLayout(LayoutKind.Sequential)]
 832      public struct UniffiForeignFutureStructVoid
 833      {
 834          public UniffiRustCallStatus @callStatus;
 835      }
 836  
 837      [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
 838      public delegate void UniffiForeignFutureCompleteVoid(
 839          ulong @callbackData,
 840          _UniFFILib.UniffiForeignFutureStructVoid @result
 841      );
 842  
 843      static _UniFFILib()
 844      {
 845          _UniFFILib.uniffiCheckContractApiVersion();
 846          _UniFFILib.uniffiCheckApiChecksums();
 847      }
 848  
 849      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 850      public static extern RustBuffer uniffi_duper_uniffi_fn_func_parse(
 851          RustBuffer @input,
 852          sbyte @parseAny,
 853          ref UniffiRustCallStatus _uniffi_out_err
 854      );
 855  
 856      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 857      public static extern RustBuffer uniffi_duper_uniffi_fn_func_serialize(
 858          RustBuffer @input,
 859          RustBuffer @options,
 860          ref UniffiRustCallStatus _uniffi_out_err
 861      );
 862  
 863      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 864      public static extern RustBuffer ffi_duper_uniffi_rustbuffer_alloc(
 865          ulong @size,
 866          ref UniffiRustCallStatus _uniffi_out_err
 867      );
 868  
 869      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 870      public static extern RustBuffer ffi_duper_uniffi_rustbuffer_from_bytes(
 871          ForeignBytes @bytes,
 872          ref UniffiRustCallStatus _uniffi_out_err
 873      );
 874  
 875      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 876      public static extern void ffi_duper_uniffi_rustbuffer_free(
 877          RustBuffer @buf,
 878          ref UniffiRustCallStatus _uniffi_out_err
 879      );
 880  
 881      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 882      public static extern RustBuffer ffi_duper_uniffi_rustbuffer_reserve(
 883          RustBuffer @buf,
 884          ulong @additional,
 885          ref UniffiRustCallStatus _uniffi_out_err
 886      );
 887  
 888      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 889      public static extern void ffi_duper_uniffi_rust_future_poll_u8(
 890          IntPtr @handle,
 891          IntPtr @callback,
 892          IntPtr @callbackData
 893      );
 894  
 895      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 896      public static extern void ffi_duper_uniffi_rust_future_cancel_u8(IntPtr @handle);
 897  
 898      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 899      public static extern void ffi_duper_uniffi_rust_future_free_u8(IntPtr @handle);
 900  
 901      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 902      public static extern byte ffi_duper_uniffi_rust_future_complete_u8(
 903          IntPtr @handle,
 904          ref UniffiRustCallStatus _uniffi_out_err
 905      );
 906  
 907      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 908      public static extern void ffi_duper_uniffi_rust_future_poll_i8(
 909          IntPtr @handle,
 910          IntPtr @callback,
 911          IntPtr @callbackData
 912      );
 913  
 914      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 915      public static extern void ffi_duper_uniffi_rust_future_cancel_i8(IntPtr @handle);
 916  
 917      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 918      public static extern void ffi_duper_uniffi_rust_future_free_i8(IntPtr @handle);
 919  
 920      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 921      public static extern sbyte ffi_duper_uniffi_rust_future_complete_i8(
 922          IntPtr @handle,
 923          ref UniffiRustCallStatus _uniffi_out_err
 924      );
 925  
 926      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 927      public static extern void ffi_duper_uniffi_rust_future_poll_u16(
 928          IntPtr @handle,
 929          IntPtr @callback,
 930          IntPtr @callbackData
 931      );
 932  
 933      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 934      public static extern void ffi_duper_uniffi_rust_future_cancel_u16(IntPtr @handle);
 935  
 936      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 937      public static extern void ffi_duper_uniffi_rust_future_free_u16(IntPtr @handle);
 938  
 939      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 940      public static extern ushort ffi_duper_uniffi_rust_future_complete_u16(
 941          IntPtr @handle,
 942          ref UniffiRustCallStatus _uniffi_out_err
 943      );
 944  
 945      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 946      public static extern void ffi_duper_uniffi_rust_future_poll_i16(
 947          IntPtr @handle,
 948          IntPtr @callback,
 949          IntPtr @callbackData
 950      );
 951  
 952      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 953      public static extern void ffi_duper_uniffi_rust_future_cancel_i16(IntPtr @handle);
 954  
 955      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 956      public static extern void ffi_duper_uniffi_rust_future_free_i16(IntPtr @handle);
 957  
 958      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 959      public static extern short ffi_duper_uniffi_rust_future_complete_i16(
 960          IntPtr @handle,
 961          ref UniffiRustCallStatus _uniffi_out_err
 962      );
 963  
 964      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 965      public static extern void ffi_duper_uniffi_rust_future_poll_u32(
 966          IntPtr @handle,
 967          IntPtr @callback,
 968          IntPtr @callbackData
 969      );
 970  
 971      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 972      public static extern void ffi_duper_uniffi_rust_future_cancel_u32(IntPtr @handle);
 973  
 974      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 975      public static extern void ffi_duper_uniffi_rust_future_free_u32(IntPtr @handle);
 976  
 977      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 978      public static extern uint ffi_duper_uniffi_rust_future_complete_u32(
 979          IntPtr @handle,
 980          ref UniffiRustCallStatus _uniffi_out_err
 981      );
 982  
 983      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 984      public static extern void ffi_duper_uniffi_rust_future_poll_i32(
 985          IntPtr @handle,
 986          IntPtr @callback,
 987          IntPtr @callbackData
 988      );
 989  
 990      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 991      public static extern void ffi_duper_uniffi_rust_future_cancel_i32(IntPtr @handle);
 992  
 993      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 994      public static extern void ffi_duper_uniffi_rust_future_free_i32(IntPtr @handle);
 995  
 996      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
 997      public static extern int ffi_duper_uniffi_rust_future_complete_i32(
 998          IntPtr @handle,
 999          ref UniffiRustCallStatus _uniffi_out_err
1000      );
1001  
1002      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1003      public static extern void ffi_duper_uniffi_rust_future_poll_u64(
1004          IntPtr @handle,
1005          IntPtr @callback,
1006          IntPtr @callbackData
1007      );
1008  
1009      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1010      public static extern void ffi_duper_uniffi_rust_future_cancel_u64(IntPtr @handle);
1011  
1012      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1013      public static extern void ffi_duper_uniffi_rust_future_free_u64(IntPtr @handle);
1014  
1015      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1016      public static extern ulong ffi_duper_uniffi_rust_future_complete_u64(
1017          IntPtr @handle,
1018          ref UniffiRustCallStatus _uniffi_out_err
1019      );
1020  
1021      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1022      public static extern void ffi_duper_uniffi_rust_future_poll_i64(
1023          IntPtr @handle,
1024          IntPtr @callback,
1025          IntPtr @callbackData
1026      );
1027  
1028      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1029      public static extern void ffi_duper_uniffi_rust_future_cancel_i64(IntPtr @handle);
1030  
1031      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1032      public static extern void ffi_duper_uniffi_rust_future_free_i64(IntPtr @handle);
1033  
1034      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1035      public static extern long ffi_duper_uniffi_rust_future_complete_i64(
1036          IntPtr @handle,
1037          ref UniffiRustCallStatus _uniffi_out_err
1038      );
1039  
1040      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1041      public static extern void ffi_duper_uniffi_rust_future_poll_f32(
1042          IntPtr @handle,
1043          IntPtr @callback,
1044          IntPtr @callbackData
1045      );
1046  
1047      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1048      public static extern void ffi_duper_uniffi_rust_future_cancel_f32(IntPtr @handle);
1049  
1050      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1051      public static extern void ffi_duper_uniffi_rust_future_free_f32(IntPtr @handle);
1052  
1053      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1054      public static extern float ffi_duper_uniffi_rust_future_complete_f32(
1055          IntPtr @handle,
1056          ref UniffiRustCallStatus _uniffi_out_err
1057      );
1058  
1059      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1060      public static extern void ffi_duper_uniffi_rust_future_poll_f64(
1061          IntPtr @handle,
1062          IntPtr @callback,
1063          IntPtr @callbackData
1064      );
1065  
1066      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1067      public static extern void ffi_duper_uniffi_rust_future_cancel_f64(IntPtr @handle);
1068  
1069      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1070      public static extern void ffi_duper_uniffi_rust_future_free_f64(IntPtr @handle);
1071  
1072      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1073      public static extern double ffi_duper_uniffi_rust_future_complete_f64(
1074          IntPtr @handle,
1075          ref UniffiRustCallStatus _uniffi_out_err
1076      );
1077  
1078      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1079      public static extern void ffi_duper_uniffi_rust_future_poll_pointer(
1080          IntPtr @handle,
1081          IntPtr @callback,
1082          IntPtr @callbackData
1083      );
1084  
1085      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1086      public static extern void ffi_duper_uniffi_rust_future_cancel_pointer(IntPtr @handle);
1087  
1088      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1089      public static extern void ffi_duper_uniffi_rust_future_free_pointer(IntPtr @handle);
1090  
1091      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1092      public static extern IntPtr ffi_duper_uniffi_rust_future_complete_pointer(
1093          IntPtr @handle,
1094          ref UniffiRustCallStatus _uniffi_out_err
1095      );
1096  
1097      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1098      public static extern void ffi_duper_uniffi_rust_future_poll_rust_buffer(
1099          IntPtr @handle,
1100          IntPtr @callback,
1101          IntPtr @callbackData
1102      );
1103  
1104      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1105      public static extern void ffi_duper_uniffi_rust_future_cancel_rust_buffer(IntPtr @handle);
1106  
1107      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1108      public static extern void ffi_duper_uniffi_rust_future_free_rust_buffer(IntPtr @handle);
1109  
1110      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1111      public static extern RustBuffer ffi_duper_uniffi_rust_future_complete_rust_buffer(
1112          IntPtr @handle,
1113          ref UniffiRustCallStatus _uniffi_out_err
1114      );
1115  
1116      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1117      public static extern void ffi_duper_uniffi_rust_future_poll_void(
1118          IntPtr @handle,
1119          IntPtr @callback,
1120          IntPtr @callbackData
1121      );
1122  
1123      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1124      public static extern void ffi_duper_uniffi_rust_future_cancel_void(IntPtr @handle);
1125  
1126      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1127      public static extern void ffi_duper_uniffi_rust_future_free_void(IntPtr @handle);
1128  
1129      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1130      public static extern void ffi_duper_uniffi_rust_future_complete_void(
1131          IntPtr @handle,
1132          ref UniffiRustCallStatus _uniffi_out_err
1133      );
1134  
1135      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1136      public static extern ushort uniffi_duper_uniffi_checksum_func_parse();
1137  
1138      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1139      public static extern ushort uniffi_duper_uniffi_checksum_func_serialize();
1140  
1141      [DllImport("duper_uniffi", CallingConvention = CallingConvention.Cdecl)]
1142      public static extern uint ffi_duper_uniffi_uniffi_contract_version();
1143  
1144      static void uniffiCheckContractApiVersion()
1145      {
1146          var scaffolding_contract_version = _UniFFILib.ffi_duper_uniffi_uniffi_contract_version();
1147          if (29 != scaffolding_contract_version)
1148          {
1149              throw new UniffiContractVersionException(
1150                  $"Duper.Ffi: uniffi bindings expected version `29`, library returned `{scaffolding_contract_version}`"
1151              );
1152          }
1153      }
1154  
1155      static void uniffiCheckApiChecksums()
1156      {
1157          {
1158              var checksum = _UniFFILib.uniffi_duper_uniffi_checksum_func_parse();
1159              if (checksum != 8398)
1160              {
1161                  throw new UniffiContractChecksumException(
1162                      $"Duper.Ffi: uniffi bindings expected function `uniffi_duper_uniffi_checksum_func_parse` checksum `8398`, library returned `{checksum}`"
1163                  );
1164              }
1165          }
1166          {
1167              var checksum = _UniFFILib.uniffi_duper_uniffi_checksum_func_serialize();
1168              if (checksum != 14365)
1169              {
1170                  throw new UniffiContractChecksumException(
1171                      $"Duper.Ffi: uniffi bindings expected function `uniffi_duper_uniffi_checksum_func_serialize` checksum `14365`, library returned `{checksum}`"
1172                  );
1173              }
1174          }
1175      }
1176  }
1177  
1178  // Public interface members begin here.
1179  
1180  #pragma warning disable 8625
1181  
1182  class FfiConverterInt64 : FfiConverter<long, long>
1183  {
1184      public static FfiConverterInt64 INSTANCE = new FfiConverterInt64();
1185  
1186      public override long Lift(long value)
1187      {
1188          return value;
1189      }
1190  
1191      public override long Read(BigEndianStream stream)
1192      {
1193          return stream.ReadLong();
1194      }
1195  
1196      public override long Lower(long value)
1197      {
1198          return value;
1199      }
1200  
1201      public override int AllocationSize(long value)
1202      {
1203          return 8;
1204      }
1205  
1206      public override void Write(long value, BigEndianStream stream)
1207      {
1208          stream.WriteLong(value);
1209      }
1210  }
1211  
1212  class FfiConverterDouble : FfiConverter<double, double>
1213  {
1214      public static FfiConverterDouble INSTANCE = new FfiConverterDouble();
1215  
1216      public override double Lift(double value)
1217      {
1218          return value;
1219      }
1220  
1221      public override double Read(BigEndianStream stream)
1222      {
1223          return stream.ReadDouble();
1224      }
1225  
1226      public override double Lower(double value)
1227      {
1228          return value;
1229      }
1230  
1231      public override int AllocationSize(double value)
1232      {
1233          return 8;
1234      }
1235  
1236      public override void Write(double value, BigEndianStream stream)
1237      {
1238          stream.WriteDouble(value);
1239      }
1240  }
1241  
1242  class FfiConverterBoolean : FfiConverter<bool, sbyte>
1243  {
1244      public static FfiConverterBoolean INSTANCE = new FfiConverterBoolean();
1245  
1246      public override bool Lift(sbyte value)
1247      {
1248          return value != 0;
1249      }
1250  
1251      public override bool Read(BigEndianStream stream)
1252      {
1253          return Lift(stream.ReadSByte());
1254      }
1255  
1256      public override sbyte Lower(bool value)
1257      {
1258          return value ? (sbyte)1 : (sbyte)0;
1259      }
1260  
1261      public override int AllocationSize(bool value)
1262      {
1263          return (sbyte)1;
1264      }
1265  
1266      public override void Write(bool value, BigEndianStream stream)
1267      {
1268          stream.WriteSByte(Lower(value));
1269      }
1270  }
1271  
1272  class FfiConverterString : FfiConverter<string, RustBuffer>
1273  {
1274      public static FfiConverterString INSTANCE = new FfiConverterString();
1275  
1276      // Note: we don't inherit from FfiConverterRustBuffer, because we use a
1277      // special encoding when lowering/lifting.  We can use `RustBuffer.len` to
1278      // store our length and avoid writing it out to the buffer.
1279      public override string Lift(RustBuffer value)
1280      {
1281          try
1282          {
1283              var bytes = value.AsStream().ReadBytes(Convert.ToInt32(value.len));
1284              return System.Text.Encoding.UTF8.GetString(bytes);
1285          }
1286          finally
1287          {
1288              RustBuffer.Free(value);
1289          }
1290      }
1291  
1292      public override string Read(BigEndianStream stream)
1293      {
1294          var length = stream.ReadInt();
1295          var bytes = stream.ReadBytes(length);
1296          return System.Text.Encoding.UTF8.GetString(bytes);
1297      }
1298  
1299      public override RustBuffer Lower(string value)
1300      {
1301          var bytes = System.Text.Encoding.UTF8.GetBytes(value);
1302          var rbuf = RustBuffer.Alloc(bytes.Length);
1303          rbuf.AsWriteableStream().WriteBytes(bytes);
1304          return rbuf;
1305      }
1306  
1307      // TODO(CS)
1308      // We aren't sure exactly how many bytes our string will be once it's UTF-8
1309      // encoded.  Allocate 3 bytes per unicode codepoint which will always be
1310      // enough.
1311      public override int AllocationSize(string value)
1312      {
1313          const int sizeForLength = 4;
1314          var sizeForString = System.Text.Encoding.UTF8.GetByteCount(value);
1315          return sizeForLength + sizeForString;
1316      }
1317  
1318      public override void Write(string value, BigEndianStream stream)
1319      {
1320          var bytes = System.Text.Encoding.UTF8.GetBytes(value);
1321          stream.WriteInt(bytes.Length);
1322          stream.WriteBytes(bytes);
1323      }
1324  }
1325  
1326  class FfiConverterByteArray : FfiConverterRustBuffer<byte[]>
1327  {
1328      public static FfiConverterByteArray INSTANCE = new FfiConverterByteArray();
1329  
1330      public override byte[] Read(BigEndianStream stream)
1331      {
1332          var length = stream.ReadInt();
1333          return stream.ReadBytes(length);
1334      }
1335  
1336      public override int AllocationSize(byte[] value)
1337      {
1338          return 4 + value.Length;
1339      }
1340  
1341      public override void Write(byte[] value, BigEndianStream stream)
1342      {
1343          stream.WriteInt(value.Length);
1344          stream.WriteBytes(value);
1345      }
1346  }
1347  
1348  internal record DuperObjectEntry(string @key, DuperValue @value) { }
1349  
1350  class FfiConverterTypeDuperObjectEntry : FfiConverterRustBuffer<DuperObjectEntry>
1351  {
1352      public static FfiConverterTypeDuperObjectEntry INSTANCE =
1353          new FfiConverterTypeDuperObjectEntry();
1354  
1355      public override DuperObjectEntry Read(BigEndianStream stream)
1356      {
1357          return new DuperObjectEntry(
1358              @key: FfiConverterString.INSTANCE.Read(stream),
1359              @value: FfiConverterTypeDuperValue.INSTANCE.Read(stream)
1360          );
1361      }
1362  
1363      public override int AllocationSize(DuperObjectEntry value)
1364      {
1365          return 0
1366              + FfiConverterString.INSTANCE.AllocationSize(value.@key)
1367              + FfiConverterTypeDuperValue.INSTANCE.AllocationSize(value.@value);
1368      }
1369  
1370      public override void Write(DuperObjectEntry value, BigEndianStream stream)
1371      {
1372          FfiConverterString.INSTANCE.Write(value.@key, stream);
1373          FfiConverterTypeDuperValue.INSTANCE.Write(value.@value, stream);
1374      }
1375  }
1376  
1377  internal record SerializeOptions(string? @indent, bool @stripIdentifiers, bool @minify) { }
1378  
1379  class FfiConverterTypeSerializeOptions : FfiConverterRustBuffer<SerializeOptions>
1380  {
1381      public static FfiConverterTypeSerializeOptions INSTANCE =
1382          new FfiConverterTypeSerializeOptions();
1383  
1384      public override SerializeOptions Read(BigEndianStream stream)
1385      {
1386          return new SerializeOptions(
1387              @indent: FfiConverterOptionalString.INSTANCE.Read(stream),
1388              @stripIdentifiers: FfiConverterBoolean.INSTANCE.Read(stream),
1389              @minify: FfiConverterBoolean.INSTANCE.Read(stream)
1390          );
1391      }
1392  
1393      public override int AllocationSize(SerializeOptions value)
1394      {
1395          return 0
1396              + FfiConverterOptionalString.INSTANCE.AllocationSize(value.@indent)
1397              + FfiConverterBoolean.INSTANCE.AllocationSize(value.@stripIdentifiers)
1398              + FfiConverterBoolean.INSTANCE.AllocationSize(value.@minify);
1399      }
1400  
1401      public override void Write(SerializeOptions value, BigEndianStream stream)
1402      {
1403          FfiConverterOptionalString.INSTANCE.Write(value.@indent, stream);
1404          FfiConverterBoolean.INSTANCE.Write(value.@stripIdentifiers, stream);
1405          FfiConverterBoolean.INSTANCE.Write(value.@minify, stream);
1406      }
1407  }
1408  
1409  internal class DuperException : UniffiException
1410  {
1411      DuperException(string message)
1412          : base(message) { }
1413  
1414      // Each variant is a nested class
1415      // Flat enums carries a string error message, so no special implementation is necessary.
1416  
1417      public class Parse : DuperException
1418      {
1419          public Parse(string message)
1420              : base(message) { }
1421      }
1422  
1423      public class SerializeOptions : DuperException
1424      {
1425          public SerializeOptions(string message)
1426              : base(message) { }
1427      }
1428  
1429      public class InvalidIdentifier : DuperException
1430      {
1431          public InvalidIdentifier(string message)
1432              : base(message) { }
1433      }
1434  
1435      public class InvalidObject : DuperException
1436      {
1437          public InvalidObject(string message)
1438              : base(message) { }
1439      }
1440  
1441      public class InvalidTemporal : DuperException
1442      {
1443          public InvalidTemporal(string message)
1444              : base(message) { }
1445      }
1446  }
1447  
1448  class FfiConverterTypeDuperError
1449      : FfiConverterRustBuffer<DuperException>,
1450          CallStatusErrorHandler<DuperException>
1451  {
1452      public static FfiConverterTypeDuperError INSTANCE = new FfiConverterTypeDuperError();
1453  
1454      public override DuperException Read(BigEndianStream stream)
1455      {
1456          var value = stream.ReadInt();
1457          switch (value)
1458          {
1459              case 1:
1460                  return new DuperException.Parse(FfiConverterString.INSTANCE.Read(stream));
1461              case 2:
1462                  return new DuperException.SerializeOptions(
1463                      FfiConverterString.INSTANCE.Read(stream)
1464                  );
1465              case 3:
1466                  return new DuperException.InvalidIdentifier(
1467                      FfiConverterString.INSTANCE.Read(stream)
1468                  );
1469              case 4:
1470                  return new DuperException.InvalidObject(FfiConverterString.INSTANCE.Read(stream));
1471              case 5:
1472                  return new DuperException.InvalidTemporal(FfiConverterString.INSTANCE.Read(stream));
1473              default:
1474                  throw new InternalException(
1475                      String.Format(
1476                          "invalid error value '{0}' in FfiConverterTypeDuperError.Read()",
1477                          value
1478                      )
1479                  );
1480          }
1481      }
1482  
1483      public override int AllocationSize(DuperException value)
1484      {
1485          return 4 + FfiConverterString.INSTANCE.AllocationSize(value.Message);
1486      }
1487  
1488      public override void Write(DuperException value, BigEndianStream stream)
1489      {
1490          switch (value)
1491          {
1492              case DuperException.Parse:
1493                  stream.WriteInt(1);
1494                  break;
1495              case DuperException.SerializeOptions:
1496                  stream.WriteInt(2);
1497                  break;
1498              case DuperException.InvalidIdentifier:
1499                  stream.WriteInt(3);
1500                  break;
1501              case DuperException.InvalidObject:
1502                  stream.WriteInt(4);
1503                  break;
1504              case DuperException.InvalidTemporal:
1505                  stream.WriteInt(5);
1506                  break;
1507              default:
1508                  throw new InternalException(
1509                      String.Format(
1510                          "invalid error value '{0}' in FfiConverterTypeDuperError.Write()",
1511                          value
1512                      )
1513                  );
1514          }
1515      }
1516  }
1517  
1518  internal record DuperValue
1519  {
1520      public record Object(string? @identifier, DuperObjectEntry[] @value) : DuperValue { }
1521  
1522      public record Array(string? @identifier, DuperValue[] @value) : DuperValue { }
1523  
1524      public record Tuple(string? @identifier, DuperValue[] @value) : DuperValue { }
1525  
1526      public record String(string? @identifier, string @value) : DuperValue { }
1527  
1528      public record Bytes(string? @identifier, byte[] @value) : DuperValue { }
1529  
1530      public record Temporal(string? @identifier, string @value) : DuperValue { }
1531  
1532      public record Integer(string? @identifier, long @value) : DuperValue { }
1533  
1534      public record Float(string? @identifier, double @value) : DuperValue { }
1535  
1536      public record Boolean(string? @identifier, bool @value) : DuperValue { }
1537  
1538      public record Null(string? @identifier) : DuperValue { }
1539  }
1540  
1541  class FfiConverterTypeDuperValue : FfiConverterRustBuffer<DuperValue>
1542  {
1543      public static FfiConverterRustBuffer<DuperValue> INSTANCE = new FfiConverterTypeDuperValue();
1544  
1545      public override DuperValue Read(BigEndianStream stream)
1546      {
1547          var value = stream.ReadInt();
1548          switch (value)
1549          {
1550              case 1:
1551                  return new DuperValue.Object(
1552                      FfiConverterOptionalString.INSTANCE.Read(stream),
1553                      FfiConverterSequenceTypeDuperObjectEntry.INSTANCE.Read(stream)
1554                  );
1555              case 2:
1556                  return new DuperValue.Array(
1557                      FfiConverterOptionalString.INSTANCE.Read(stream),
1558                      FfiConverterSequenceTypeDuperValue.INSTANCE.Read(stream)
1559                  );
1560              case 3:
1561                  return new DuperValue.Tuple(
1562                      FfiConverterOptionalString.INSTANCE.Read(stream),
1563                      FfiConverterSequenceTypeDuperValue.INSTANCE.Read(stream)
1564                  );
1565              case 4:
1566                  return new DuperValue.String(
1567                      FfiConverterOptionalString.INSTANCE.Read(stream),
1568                      FfiConverterString.INSTANCE.Read(stream)
1569                  );
1570              case 5:
1571                  return new DuperValue.Bytes(
1572                      FfiConverterOptionalString.INSTANCE.Read(stream),
1573                      FfiConverterByteArray.INSTANCE.Read(stream)
1574                  );
1575              case 6:
1576                  return new DuperValue.Temporal(
1577                      FfiConverterOptionalString.INSTANCE.Read(stream),
1578                      FfiConverterString.INSTANCE.Read(stream)
1579                  );
1580              case 7:
1581                  return new DuperValue.Integer(
1582                      FfiConverterOptionalString.INSTANCE.Read(stream),
1583                      FfiConverterInt64.INSTANCE.Read(stream)
1584                  );
1585              case 8:
1586                  return new DuperValue.Float(
1587                      FfiConverterOptionalString.INSTANCE.Read(stream),
1588                      FfiConverterDouble.INSTANCE.Read(stream)
1589                  );
1590              case 9:
1591                  return new DuperValue.Boolean(
1592                      FfiConverterOptionalString.INSTANCE.Read(stream),
1593                      FfiConverterBoolean.INSTANCE.Read(stream)
1594                  );
1595              case 10:
1596                  return new DuperValue.Null(FfiConverterOptionalString.INSTANCE.Read(stream));
1597              default:
1598                  throw new InternalException(
1599                      String.Format(
1600                          "invalid enum value '{0}' in FfiConverterTypeDuperValue.Read()",
1601                          value
1602                      )
1603                  );
1604          }
1605      }
1606  
1607      public override int AllocationSize(DuperValue value)
1608      {
1609          switch (value)
1610          {
1611              case DuperValue.Object variant_value:
1612                  return 4
1613                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1614                      + FfiConverterSequenceTypeDuperObjectEntry.INSTANCE.AllocationSize(
1615                          variant_value.@value
1616                      );
1617              case DuperValue.Array variant_value:
1618                  return 4
1619                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1620                      + FfiConverterSequenceTypeDuperValue.INSTANCE.AllocationSize(
1621                          variant_value.@value
1622                      );
1623              case DuperValue.Tuple variant_value:
1624                  return 4
1625                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1626                      + FfiConverterSequenceTypeDuperValue.INSTANCE.AllocationSize(
1627                          variant_value.@value
1628                      );
1629              case DuperValue.String variant_value:
1630                  return 4
1631                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1632                      + FfiConverterString.INSTANCE.AllocationSize(variant_value.@value);
1633              case DuperValue.Bytes variant_value:
1634                  return 4
1635                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1636                      + FfiConverterByteArray.INSTANCE.AllocationSize(variant_value.@value);
1637              case DuperValue.Temporal variant_value:
1638                  return 4
1639                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1640                      + FfiConverterString.INSTANCE.AllocationSize(variant_value.@value);
1641              case DuperValue.Integer variant_value:
1642                  return 4
1643                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1644                      + FfiConverterInt64.INSTANCE.AllocationSize(variant_value.@value);
1645              case DuperValue.Float variant_value:
1646                  return 4
1647                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1648                      + FfiConverterDouble.INSTANCE.AllocationSize(variant_value.@value);
1649              case DuperValue.Boolean variant_value:
1650                  return 4
1651                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier)
1652                      + FfiConverterBoolean.INSTANCE.AllocationSize(variant_value.@value);
1653              case DuperValue.Null variant_value:
1654                  return 4
1655                      + FfiConverterOptionalString.INSTANCE.AllocationSize(variant_value.@identifier);
1656              default:
1657                  throw new InternalException(
1658                      String.Format(
1659                          "invalid enum value '{0}' in FfiConverterTypeDuperValue.AllocationSize()",
1660                          value
1661                      )
1662                  );
1663          }
1664      }
1665  
1666      public override void Write(DuperValue value, BigEndianStream stream)
1667      {
1668          switch (value)
1669          {
1670              case DuperValue.Object variant_value:
1671                  stream.WriteInt(1);
1672                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1673                  FfiConverterSequenceTypeDuperObjectEntry.INSTANCE.Write(
1674                      variant_value.@value,
1675                      stream
1676                  );
1677                  break;
1678              case DuperValue.Array variant_value:
1679                  stream.WriteInt(2);
1680                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1681                  FfiConverterSequenceTypeDuperValue.INSTANCE.Write(variant_value.@value, stream);
1682                  break;
1683              case DuperValue.Tuple variant_value:
1684                  stream.WriteInt(3);
1685                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1686                  FfiConverterSequenceTypeDuperValue.INSTANCE.Write(variant_value.@value, stream);
1687                  break;
1688              case DuperValue.String variant_value:
1689                  stream.WriteInt(4);
1690                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1691                  FfiConverterString.INSTANCE.Write(variant_value.@value, stream);
1692                  break;
1693              case DuperValue.Bytes variant_value:
1694                  stream.WriteInt(5);
1695                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1696                  FfiConverterByteArray.INSTANCE.Write(variant_value.@value, stream);
1697                  break;
1698              case DuperValue.Temporal variant_value:
1699                  stream.WriteInt(6);
1700                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1701                  FfiConverterString.INSTANCE.Write(variant_value.@value, stream);
1702                  break;
1703              case DuperValue.Integer variant_value:
1704                  stream.WriteInt(7);
1705                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1706                  FfiConverterInt64.INSTANCE.Write(variant_value.@value, stream);
1707                  break;
1708              case DuperValue.Float variant_value:
1709                  stream.WriteInt(8);
1710                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1711                  FfiConverterDouble.INSTANCE.Write(variant_value.@value, stream);
1712                  break;
1713              case DuperValue.Boolean variant_value:
1714                  stream.WriteInt(9);
1715                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1716                  FfiConverterBoolean.INSTANCE.Write(variant_value.@value, stream);
1717                  break;
1718              case DuperValue.Null variant_value:
1719                  stream.WriteInt(10);
1720                  FfiConverterOptionalString.INSTANCE.Write(variant_value.@identifier, stream);
1721                  break;
1722              default:
1723                  throw new InternalException(
1724                      String.Format(
1725                          "invalid enum value '{0}' in FfiConverterTypeDuperValue.Write()",
1726                          value
1727                      )
1728                  );
1729          }
1730      }
1731  }
1732  
1733  class FfiConverterOptionalString : FfiConverterRustBuffer<string?>
1734  {
1735      public static FfiConverterOptionalString INSTANCE = new FfiConverterOptionalString();
1736  
1737      public override string? Read(BigEndianStream stream)
1738      {
1739          if (stream.ReadByte() == 0)
1740          {
1741              return null;
1742          }
1743          return FfiConverterString.INSTANCE.Read(stream);
1744      }
1745  
1746      public override int AllocationSize(string? value)
1747      {
1748          if (value == null)
1749          {
1750              return 1;
1751          }
1752          else
1753          {
1754              return 1 + FfiConverterString.INSTANCE.AllocationSize((string)value);
1755          }
1756      }
1757  
1758      public override void Write(string? value, BigEndianStream stream)
1759      {
1760          if (value == null)
1761          {
1762              stream.WriteByte(0);
1763          }
1764          else
1765          {
1766              stream.WriteByte(1);
1767              FfiConverterString.INSTANCE.Write((string)value, stream);
1768          }
1769      }
1770  }
1771  
1772  class FfiConverterOptionalTypeSerializeOptions : FfiConverterRustBuffer<SerializeOptions?>
1773  {
1774      public static FfiConverterOptionalTypeSerializeOptions INSTANCE =
1775          new FfiConverterOptionalTypeSerializeOptions();
1776  
1777      public override SerializeOptions? Read(BigEndianStream stream)
1778      {
1779          if (stream.ReadByte() == 0)
1780          {
1781              return null;
1782          }
1783          return FfiConverterTypeSerializeOptions.INSTANCE.Read(stream);
1784      }
1785  
1786      public override int AllocationSize(SerializeOptions? value)
1787      {
1788          if (value == null)
1789          {
1790              return 1;
1791          }
1792          else
1793          {
1794              return 1
1795                  + FfiConverterTypeSerializeOptions.INSTANCE.AllocationSize((SerializeOptions)value);
1796          }
1797      }
1798  
1799      public override void Write(SerializeOptions? value, BigEndianStream stream)
1800      {
1801          if (value == null)
1802          {
1803              stream.WriteByte(0);
1804          }
1805          else
1806          {
1807              stream.WriteByte(1);
1808              FfiConverterTypeSerializeOptions.INSTANCE.Write((SerializeOptions)value, stream);
1809          }
1810      }
1811  }
1812  
1813  class FfiConverterSequenceTypeDuperObjectEntry : FfiConverterRustBuffer<DuperObjectEntry[]>
1814  {
1815      public static FfiConverterSequenceTypeDuperObjectEntry INSTANCE =
1816          new FfiConverterSequenceTypeDuperObjectEntry();
1817  
1818      public override DuperObjectEntry[] Read(BigEndianStream stream)
1819      {
1820          var length = stream.ReadInt();
1821          if (length == 0)
1822          {
1823              return [];
1824          }
1825  
1826          var result = new DuperObjectEntry[(length)];
1827          var readFn = FfiConverterTypeDuperObjectEntry.INSTANCE.Read;
1828          for (int i = 0; i < length; i++)
1829          {
1830              result[i] = readFn(stream);
1831          }
1832          return result;
1833      }
1834  
1835      public override int AllocationSize(DuperObjectEntry[] value)
1836      {
1837          var sizeForLength = 4;
1838  
1839          // details/1-empty-list-as-default-method-parameter.md
1840          if (value == null)
1841          {
1842              return sizeForLength;
1843          }
1844  
1845          var allocationSizeFn = FfiConverterTypeDuperObjectEntry.INSTANCE.AllocationSize;
1846          var sizeForItems = value.Sum(item => allocationSizeFn(item));
1847          return sizeForLength + sizeForItems;
1848      }
1849  
1850      public override void Write(DuperObjectEntry[] value, BigEndianStream stream)
1851      {
1852          // details/1-empty-list-as-default-method-parameter.md
1853          if (value == null)
1854          {
1855              stream.WriteInt(0);
1856              return;
1857          }
1858  
1859          stream.WriteInt(value.Length);
1860          var writerFn = FfiConverterTypeDuperObjectEntry.INSTANCE.Write;
1861          value.ForEach(item => writerFn(item, stream));
1862      }
1863  }
1864  
1865  class FfiConverterSequenceTypeDuperValue : FfiConverterRustBuffer<DuperValue[]>
1866  {
1867      public static FfiConverterSequenceTypeDuperValue INSTANCE =
1868          new FfiConverterSequenceTypeDuperValue();
1869  
1870      public override DuperValue[] Read(BigEndianStream stream)
1871      {
1872          var length = stream.ReadInt();
1873          if (length == 0)
1874          {
1875              return [];
1876          }
1877  
1878          var result = new DuperValue[(length)];
1879          var readFn = FfiConverterTypeDuperValue.INSTANCE.Read;
1880          for (int i = 0; i < length; i++)
1881          {
1882              result[i] = readFn(stream);
1883          }
1884          return result;
1885      }
1886  
1887      public override int AllocationSize(DuperValue[] value)
1888      {
1889          var sizeForLength = 4;
1890  
1891          // details/1-empty-list-as-default-method-parameter.md
1892          if (value == null)
1893          {
1894              return sizeForLength;
1895          }
1896  
1897          var allocationSizeFn = FfiConverterTypeDuperValue.INSTANCE.AllocationSize;
1898          var sizeForItems = value.Sum(item => allocationSizeFn(item));
1899          return sizeForLength + sizeForItems;
1900      }
1901  
1902      public override void Write(DuperValue[] value, BigEndianStream stream)
1903      {
1904          // details/1-empty-list-as-default-method-parameter.md
1905          if (value == null)
1906          {
1907              stream.WriteInt(0);
1908              return;
1909          }
1910  
1911          stream.WriteInt(value.Length);
1912          var writerFn = FfiConverterTypeDuperValue.INSTANCE.Write;
1913          value.ForEach(item => writerFn(item, stream));
1914      }
1915  }
1916  #pragma warning restore 8625
1917  internal static class Duper
1918  {
1919      /// <exception cref="DuperException"></exception>
1920      public static DuperValue Parse(string @input, bool @parseAny)
1921      {
1922          return FfiConverterTypeDuperValue.INSTANCE.Lift(
1923              _UniffiHelpers.RustCallWithError(
1924                  FfiConverterTypeDuperError.INSTANCE,
1925                  (ref UniffiRustCallStatus _status) =>
1926                      _UniFFILib.uniffi_duper_uniffi_fn_func_parse(
1927                          FfiConverterString.INSTANCE.Lower(@input),
1928                          FfiConverterBoolean.INSTANCE.Lower(@parseAny),
1929                          ref _status
1930                      )
1931              )
1932          );
1933      }
1934  
1935      /// <exception cref="DuperException"></exception>
1936      public static string Serialize(DuperValue @input, SerializeOptions? @options)
1937      {
1938          return FfiConverterString.INSTANCE.Lift(
1939              _UniffiHelpers.RustCallWithError(
1940                  FfiConverterTypeDuperError.INSTANCE,
1941                  (ref UniffiRustCallStatus _status) =>
1942                      _UniFFILib.uniffi_duper_uniffi_fn_func_serialize(
1943                          FfiConverterTypeDuperValue.INSTANCE.Lower(@input),
1944                          FfiConverterOptionalTypeSerializeOptions.INSTANCE.Lower(@options),
1945                          ref _status
1946                      )
1947              )
1948          );
1949      }
1950  }