1use crate::platform::{self, OsIpcChannel, OsIpcReceiver, OsIpcReceiverSet, OsIpcSender};
11use crate::platform::{
12 OsIpcOneShotServer, OsIpcSelectionResult, OsIpcSharedMemory, OsOpaqueIpcChannel,
13};
14
15use bincode;
16use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
17use std::cell::RefCell;
18use std::cmp::min;
19use std::error::Error as StdError;
20use std::fmt::{self, Debug, Formatter};
21use std::io;
22use std::marker::PhantomData;
23use std::mem;
24use std::ops::Deref;
25use std::time::Duration;
26
27thread_local! {
28 static OS_IPC_CHANNELS_FOR_DESERIALIZATION: RefCell<Vec<OsOpaqueIpcChannel>> =
29 const { RefCell::new(Vec::new()) };
30
31 static OS_IPC_SHARED_MEMORY_REGIONS_FOR_DESERIALIZATION:
32 RefCell<Vec<Option<OsIpcSharedMemory>>> = const { RefCell::new(Vec::new()) };
33
34 static OS_IPC_CHANNELS_FOR_SERIALIZATION: RefCell<Vec<OsIpcChannel>> = const { RefCell::new(Vec::new()) };
35
36 static OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION: RefCell<Vec<OsIpcSharedMemory>> =
37 const { RefCell::new(Vec::new()) }
38}
39
40#[derive(Debug)]
41pub enum IpcError {
42 Bincode(bincode::Error),
43 Io(io::Error),
44 Disconnected,
45}
46
47impl fmt::Display for IpcError {
48 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
49 match *self {
50 IpcError::Bincode(ref err) => write!(fmt, "bincode error: {err}"),
51 IpcError::Io(ref err) => write!(fmt, "io error: {err}"),
52 IpcError::Disconnected => write!(fmt, "disconnected"),
53 }
54 }
55}
56
57impl StdError for IpcError {
58 fn source(&self) -> Option<&(dyn StdError + 'static)> {
59 match *self {
60 IpcError::Bincode(ref err) => Some(err),
61 IpcError::Io(ref err) => Some(err),
62 IpcError::Disconnected => None,
63 }
64 }
65}
66
67#[derive(Debug)]
68pub enum TryRecvError {
69 IpcError(IpcError),
70 Empty,
71}
72
73impl fmt::Display for TryRecvError {
74 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
75 match *self {
76 TryRecvError::IpcError(ref err) => write!(fmt, "ipc error: {err}"),
77 TryRecvError::Empty => write!(fmt, "empty"),
78 }
79 }
80}
81
82impl StdError for TryRecvError {
83 fn source(&self) -> Option<&(dyn StdError + 'static)> {
84 match *self {
85 TryRecvError::IpcError(ref err) => Some(err),
86 TryRecvError::Empty => None,
87 }
88 }
89}
90
91pub fn channel<T>() -> Result<(IpcSender<T>, IpcReceiver<T>), io::Error>
122where
123 T: for<'de> Deserialize<'de> + Serialize,
124{
125 let (os_sender, os_receiver) = platform::channel()?;
126 let ipc_receiver = IpcReceiver {
127 os_receiver,
128 phantom: PhantomData,
129 };
130 let ipc_sender = IpcSender {
131 os_sender,
132 phantom: PhantomData,
133 };
134 Ok((ipc_sender, ipc_receiver))
135}
136
137pub fn bytes_channel() -> Result<(IpcBytesSender, IpcBytesReceiver), io::Error> {
166 let (os_sender, os_receiver) = platform::channel()?;
167 let ipc_bytes_receiver = IpcBytesReceiver { os_receiver };
168 let ipc_bytes_sender = IpcBytesSender { os_sender };
169 Ok((ipc_bytes_sender, ipc_bytes_receiver))
170}
171
172#[derive(Debug)]
240pub struct IpcReceiver<T> {
241 os_receiver: OsIpcReceiver,
242 phantom: PhantomData<T>,
243}
244
245impl<T> IpcReceiver<T>
246where
247 T: for<'de> Deserialize<'de> + Serialize,
248{
249 pub fn recv(&self) -> Result<T, IpcError> {
251 self.os_receiver.recv()?.to().map_err(IpcError::Bincode)
252 }
253
254 pub fn try_recv(&self) -> Result<T, TryRecvError> {
256 self.os_receiver
257 .try_recv()?
258 .to()
259 .map_err(IpcError::Bincode)
260 .map_err(TryRecvError::IpcError)
261 }
262
263 pub fn try_recv_timeout(&self, duration: Duration) -> Result<T, TryRecvError> {
270 self.os_receiver
271 .try_recv_timeout(duration)?
272 .to()
273 .map_err(IpcError::Bincode)
274 .map_err(TryRecvError::IpcError)
275 }
276
277 pub fn to_opaque(self) -> OpaqueIpcReceiver {
281 OpaqueIpcReceiver {
282 os_receiver: self.os_receiver,
283 }
284 }
285}
286
287impl<'de, T> Deserialize<'de> for IpcReceiver<T> {
288 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
289 where
290 D: Deserializer<'de>,
291 {
292 let os_receiver = deserialize_os_ipc_receiver(deserializer)?;
293 Ok(IpcReceiver {
294 os_receiver,
295 phantom: PhantomData,
296 })
297 }
298}
299
300impl<T> Serialize for IpcReceiver<T> {
301 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
302 where
303 S: Serializer,
304 {
305 serialize_os_ipc_receiver(&self.os_receiver, serializer)
306 }
307}
308
309#[derive(Debug)]
330pub struct IpcSender<T> {
331 os_sender: OsIpcSender,
332 phantom: PhantomData<T>,
333}
334
335impl<T> Clone for IpcSender<T>
336where
337 T: Serialize,
338{
339 fn clone(&self) -> IpcSender<T> {
340 IpcSender {
341 os_sender: self.os_sender.clone(),
342 phantom: PhantomData,
343 }
344 }
345}
346
347impl<T> IpcSender<T>
348where
349 T: Serialize,
350{
351 pub fn connect(name: String) -> Result<IpcSender<T>, io::Error> {
360 Ok(IpcSender {
361 os_sender: OsIpcSender::connect(name)?,
362 phantom: PhantomData,
363 })
364 }
365
366 pub fn send(&self, data: T) -> Result<(), bincode::Error> {
368 let mut bytes = Vec::with_capacity(4096);
369 OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| {
370 OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION.with(
371 |os_ipc_shared_memory_regions_for_serialization| {
372 let old_os_ipc_channels =
373 mem::take(&mut *os_ipc_channels_for_serialization.borrow_mut());
374 let old_os_ipc_shared_memory_regions = mem::take(
375 &mut *os_ipc_shared_memory_regions_for_serialization.borrow_mut(),
376 );
377 let os_ipc_shared_memory_regions;
378 let os_ipc_channels;
379 {
380 bincode::serialize_into(&mut bytes, &data)?;
381 os_ipc_channels = mem::replace(
382 &mut *os_ipc_channels_for_serialization.borrow_mut(),
383 old_os_ipc_channels,
384 );
385 os_ipc_shared_memory_regions = mem::replace(
386 &mut *os_ipc_shared_memory_regions_for_serialization.borrow_mut(),
387 old_os_ipc_shared_memory_regions,
388 );
389 };
390 Ok(self.os_sender.send(
391 &bytes[..],
392 os_ipc_channels,
393 os_ipc_shared_memory_regions,
394 )?)
395 },
396 )
397 })
398 }
399
400 pub fn to_opaque(self) -> OpaqueIpcSender {
401 OpaqueIpcSender {
402 os_sender: self.os_sender,
403 }
404 }
405}
406
407impl<'de, T> Deserialize<'de> for IpcSender<T> {
408 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
409 where
410 D: Deserializer<'de>,
411 {
412 let os_sender = deserialize_os_ipc_sender(deserializer)?;
413 Ok(IpcSender {
414 os_sender,
415 phantom: PhantomData,
416 })
417 }
418}
419
420impl<T> Serialize for IpcSender<T> {
421 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
422 where
423 S: Serializer,
424 {
425 serialize_os_ipc_sender(&self.os_sender, serializer)
426 }
427}
428
429pub struct IpcReceiverSet {
464 os_receiver_set: OsIpcReceiverSet,
465}
466
467impl IpcReceiverSet {
468 pub fn new() -> Result<IpcReceiverSet, io::Error> {
476 Ok(IpcReceiverSet {
477 os_receiver_set: OsIpcReceiverSet::new()?,
478 })
479 }
480
481 pub fn add<T>(&mut self, receiver: IpcReceiver<T>) -> Result<u64, io::Error>
484 where
485 T: for<'de> Deserialize<'de> + Serialize,
486 {
487 Ok(self.os_receiver_set.add(receiver.os_receiver)?)
488 }
489
490 pub fn add_opaque(&mut self, receiver: OpaqueIpcReceiver) -> Result<u64, io::Error> {
493 Ok(self.os_receiver_set.add(receiver.os_receiver)?)
494 }
495
496 pub fn select(&mut self) -> Result<Vec<IpcSelectionResult>, io::Error> {
502 let results = self.os_receiver_set.select()?;
503 Ok(results
504 .into_iter()
505 .map(|result| match result {
506 OsIpcSelectionResult::DataReceived(os_receiver_id, ipc_message) => {
507 IpcSelectionResult::MessageReceived(os_receiver_id, ipc_message)
508 },
509 OsIpcSelectionResult::ChannelClosed(os_receiver_id) => {
510 IpcSelectionResult::ChannelClosed(os_receiver_id)
511 },
512 })
513 .collect())
514 }
515}
516
517#[derive(Clone, Debug, PartialEq)]
531pub struct IpcSharedMemory {
532 os_shared_memory: Option<OsIpcSharedMemory>,
534}
535
536impl Deref for IpcSharedMemory {
537 type Target = [u8];
538
539 #[inline]
540 fn deref(&self) -> &[u8] {
541 if let Some(os_shared_memory) = &self.os_shared_memory {
542 os_shared_memory
543 } else {
544 &[]
545 }
546 }
547}
548
549impl IpcSharedMemory {
550 #[inline]
558 pub unsafe fn deref_mut(&mut self) -> &mut [u8] {
559 if let Some(os_shared_memory) = &mut self.os_shared_memory {
560 os_shared_memory.deref_mut()
561 } else {
562 &mut []
563 }
564 }
565}
566
567impl<'de> Deserialize<'de> for IpcSharedMemory {
568 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
569 where
570 D: Deserializer<'de>,
571 {
572 let index: usize = Deserialize::deserialize(deserializer)?;
573 if index == usize::MAX {
574 return Ok(IpcSharedMemory::empty());
575 }
576
577 let os_shared_memory = OS_IPC_SHARED_MEMORY_REGIONS_FOR_DESERIALIZATION.with(
578 |os_ipc_shared_memory_regions_for_deserialization| {
579 let mut regions = os_ipc_shared_memory_regions_for_deserialization.borrow_mut();
580 let Some(region) = regions.get_mut(index) else {
581 return Err(format!("Cannot consume shared memory region at index {index}, there are only {} regions available", regions.len()));
582 };
583
584 region.take().ok_or_else(|| format!("Shared memory region {index} has already been consumed"))
585 },
586 ).map_err(D::Error::custom)?;
587
588 Ok(IpcSharedMemory {
589 os_shared_memory: Some(os_shared_memory),
590 })
591 }
592}
593
594impl Serialize for IpcSharedMemory {
595 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
596 where
597 S: Serializer,
598 {
599 if let Some(os_shared_memory) = &self.os_shared_memory {
600 let index = OS_IPC_SHARED_MEMORY_REGIONS_FOR_SERIALIZATION.with(
601 |os_ipc_shared_memory_regions_for_serialization| {
602 let mut os_ipc_shared_memory_regions_for_serialization =
603 os_ipc_shared_memory_regions_for_serialization.borrow_mut();
604 let index = os_ipc_shared_memory_regions_for_serialization.len();
605 os_ipc_shared_memory_regions_for_serialization.push(os_shared_memory.clone());
606 index
607 },
608 );
609 debug_assert!(index < usize::MAX);
610 index
611 } else {
612 usize::MAX
613 }
614 .serialize(serializer)
615 }
616}
617
618impl IpcSharedMemory {
619 const fn empty() -> Self {
620 Self {
621 os_shared_memory: None,
622 }
623 }
624
625 pub fn from_bytes(bytes: &[u8]) -> IpcSharedMemory {
627 if bytes.is_empty() {
628 IpcSharedMemory::empty()
629 } else {
630 IpcSharedMemory {
631 os_shared_memory: Some(OsIpcSharedMemory::from_bytes(bytes)),
632 }
633 }
634 }
635
636 pub fn from_byte(byte: u8, length: usize) -> IpcSharedMemory {
639 if length == 0 {
640 IpcSharedMemory::empty()
641 } else {
642 IpcSharedMemory {
643 os_shared_memory: Some(OsIpcSharedMemory::from_byte(byte, length)),
644 }
645 }
646 }
647}
648
649pub enum IpcSelectionResult {
653 MessageReceived(u64, IpcMessage),
656 ChannelClosed(u64),
659}
660
661impl IpcSelectionResult {
662 pub fn unwrap(self) -> (u64, IpcMessage) {
673 match self {
674 IpcSelectionResult::MessageReceived(id, message) => (id, message),
675 IpcSelectionResult::ChannelClosed(id) => {
676 panic!("IpcSelectionResult::unwrap(): channel {id} closed")
677 },
678 }
679 }
680}
681
682#[derive(PartialEq)]
688pub struct IpcMessage {
689 pub(crate) data: Vec<u8>,
690 pub(crate) os_ipc_channels: Vec<OsOpaqueIpcChannel>,
691 pub(crate) os_ipc_shared_memory_regions: Vec<OsIpcSharedMemory>,
692}
693
694impl IpcMessage {
695 pub fn from_data(data: Vec<u8>) -> Self {
698 Self {
699 data,
700 os_ipc_channels: vec![],
701 os_ipc_shared_memory_regions: vec![],
702 }
703 }
704}
705
706impl Debug for IpcMessage {
707 fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
708 match String::from_utf8(self.data.clone()) {
709 Ok(string) => string.chars().take(256).collect::<String>().fmt(formatter),
710 Err(..) => self.data[0..min(self.data.len(), 256)].fmt(formatter),
711 }
712 }
713}
714
715impl IpcMessage {
716 pub(crate) fn new(
717 data: Vec<u8>,
718 os_ipc_channels: Vec<OsOpaqueIpcChannel>,
719 os_ipc_shared_memory_regions: Vec<OsIpcSharedMemory>,
720 ) -> IpcMessage {
721 IpcMessage {
722 data,
723 os_ipc_channels,
724 os_ipc_shared_memory_regions,
725 }
726 }
727
728 pub fn to<T>(mut self) -> Result<T, bincode::Error>
730 where
731 T: for<'de> Deserialize<'de> + Serialize,
732 {
733 OS_IPC_CHANNELS_FOR_DESERIALIZATION.with(|os_ipc_channels_for_deserialization| {
734 OS_IPC_SHARED_MEMORY_REGIONS_FOR_DESERIALIZATION.with(
735 |os_ipc_shared_memory_regions_for_deserialization| {
736 mem::swap(
737 &mut *os_ipc_channels_for_deserialization.borrow_mut(),
738 &mut self.os_ipc_channels,
739 );
740 let old_ipc_shared_memory_regions_for_deserialization = mem::replace(
741 &mut *os_ipc_shared_memory_regions_for_deserialization.borrow_mut(),
742 self.os_ipc_shared_memory_regions
743 .into_iter()
744 .map(Some)
745 .collect(),
746 );
747 let result = bincode::deserialize(&self.data[..]);
748 *os_ipc_shared_memory_regions_for_deserialization.borrow_mut() =
749 old_ipc_shared_memory_regions_for_deserialization;
750 mem::swap(
751 &mut *os_ipc_channels_for_deserialization.borrow_mut(),
752 &mut self.os_ipc_channels,
753 );
754 result
757 },
758 )
759 })
760 }
761}
762
763#[derive(Clone, Debug)]
764pub struct OpaqueIpcSender {
765 os_sender: OsIpcSender,
766}
767
768impl OpaqueIpcSender {
769 pub fn to<'de, T>(self) -> IpcSender<T>
770 where
771 T: Deserialize<'de> + Serialize,
772 {
773 IpcSender {
774 os_sender: self.os_sender,
775 phantom: PhantomData,
776 }
777 }
778}
779
780impl<'de> Deserialize<'de> for OpaqueIpcSender {
781 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
782 where
783 D: Deserializer<'de>,
784 {
785 let os_sender = deserialize_os_ipc_sender(deserializer)?;
786 Ok(OpaqueIpcSender { os_sender })
787 }
788}
789
790impl Serialize for OpaqueIpcSender {
791 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
792 where
793 S: Serializer,
794 {
795 serialize_os_ipc_sender(&self.os_sender, serializer)
796 }
797}
798
799#[derive(Debug)]
800pub struct OpaqueIpcReceiver {
801 os_receiver: OsIpcReceiver,
802}
803
804impl OpaqueIpcReceiver {
805 pub fn to<'de, T>(self) -> IpcReceiver<T>
806 where
807 T: Deserialize<'de> + Serialize,
808 {
809 IpcReceiver {
810 os_receiver: self.os_receiver,
811 phantom: PhantomData,
812 }
813 }
814}
815
816impl<'de> Deserialize<'de> for OpaqueIpcReceiver {
817 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
818 where
819 D: Deserializer<'de>,
820 {
821 let os_receiver = deserialize_os_ipc_receiver(deserializer)?;
822 Ok(OpaqueIpcReceiver { os_receiver })
823 }
824}
825
826impl Serialize for OpaqueIpcReceiver {
827 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
828 where
829 S: Serializer,
830 {
831 serialize_os_ipc_receiver(&self.os_receiver, serializer)
832 }
833}
834
835pub struct IpcOneShotServer<T> {
870 os_server: OsIpcOneShotServer,
871 phantom: PhantomData<T>,
872}
873
874impl<T> IpcOneShotServer<T>
875where
876 T: for<'de> Deserialize<'de> + Serialize,
877{
878 pub fn new() -> Result<(IpcOneShotServer<T>, String), io::Error> {
879 let (os_server, name) = OsIpcOneShotServer::new()?;
880 Ok((
881 IpcOneShotServer {
882 os_server,
883 phantom: PhantomData,
884 },
885 name,
886 ))
887 }
888
889 pub fn accept(self) -> Result<(IpcReceiver<T>, T), bincode::Error> {
890 let (os_receiver, ipc_message) = self.os_server.accept()?;
891 Ok((
892 IpcReceiver {
893 os_receiver,
894 phantom: PhantomData,
895 },
896 ipc_message.to()?,
897 ))
898 }
899}
900
901#[derive(Debug)]
903pub struct IpcBytesReceiver {
904 os_receiver: OsIpcReceiver,
905}
906
907impl IpcBytesReceiver {
908 #[inline]
910 pub fn recv(&self) -> Result<Vec<u8>, IpcError> {
911 match self.os_receiver.recv() {
912 Ok(ipc_message) => Ok(ipc_message.data),
913 Err(err) => Err(err.into()),
914 }
915 }
916
917 pub fn try_recv(&self) -> Result<Vec<u8>, TryRecvError> {
919 match self.os_receiver.try_recv() {
920 Ok(ipc_message) => Ok(ipc_message.data),
921 Err(err) => Err(err.into()),
922 }
923 }
924}
925
926impl<'de> Deserialize<'de> for IpcBytesReceiver {
927 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
928 where
929 D: Deserializer<'de>,
930 {
931 let os_receiver = deserialize_os_ipc_receiver(deserializer)?;
932 Ok(IpcBytesReceiver { os_receiver })
933 }
934}
935
936impl Serialize for IpcBytesReceiver {
937 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
938 where
939 S: Serializer,
940 {
941 serialize_os_ipc_receiver(&self.os_receiver, serializer)
942 }
943}
944
945#[derive(Debug)]
947pub struct IpcBytesSender {
948 os_sender: OsIpcSender,
949}
950
951impl Clone for IpcBytesSender {
952 fn clone(&self) -> IpcBytesSender {
953 IpcBytesSender {
954 os_sender: self.os_sender.clone(),
955 }
956 }
957}
958
959impl<'de> Deserialize<'de> for IpcBytesSender {
960 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
961 where
962 D: Deserializer<'de>,
963 {
964 let os_sender = deserialize_os_ipc_sender(deserializer)?;
965 Ok(IpcBytesSender { os_sender })
966 }
967}
968
969impl Serialize for IpcBytesSender {
970 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
971 where
972 S: Serializer,
973 {
974 serialize_os_ipc_sender(&self.os_sender, serializer)
975 }
976}
977
978impl IpcBytesSender {
979 #[inline]
980 pub fn send(&self, data: &[u8]) -> Result<(), io::Error> {
981 self.os_sender
982 .send(data, vec![], vec![])
983 .map_err(io::Error::from)
984 }
985}
986
987fn serialize_os_ipc_sender<S>(os_ipc_sender: &OsIpcSender, serializer: S) -> Result<S::Ok, S::Error>
988where
989 S: Serializer,
990{
991 let index = OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| {
992 let mut os_ipc_channels_for_serialization = os_ipc_channels_for_serialization.borrow_mut();
993 let index = os_ipc_channels_for_serialization.len();
994 os_ipc_channels_for_serialization.push(OsIpcChannel::Sender(os_ipc_sender.clone()));
995 index
996 });
997 index.serialize(serializer)
998}
999
1000fn deserialize_os_ipc_sender<'de, D>(deserializer: D) -> Result<OsIpcSender, D::Error>
1001where
1002 D: Deserializer<'de>,
1003{
1004 let index: usize = Deserialize::deserialize(deserializer)?;
1005 OS_IPC_CHANNELS_FOR_DESERIALIZATION.with(|os_ipc_channels_for_deserialization| {
1006 Ok(os_ipc_channels_for_deserialization.borrow_mut()[index].to_sender())
1009 })
1010}
1011
1012fn serialize_os_ipc_receiver<S>(
1013 os_receiver: &OsIpcReceiver,
1014 serializer: S,
1015) -> Result<S::Ok, S::Error>
1016where
1017 S: Serializer,
1018{
1019 let index = OS_IPC_CHANNELS_FOR_SERIALIZATION.with(|os_ipc_channels_for_serialization| {
1020 let mut os_ipc_channels_for_serialization = os_ipc_channels_for_serialization.borrow_mut();
1021 let index = os_ipc_channels_for_serialization.len();
1022 os_ipc_channels_for_serialization.push(OsIpcChannel::Receiver(os_receiver.consume()));
1023 index
1024 });
1025 index.serialize(serializer)
1026}
1027
1028fn deserialize_os_ipc_receiver<'de, D>(deserializer: D) -> Result<OsIpcReceiver, D::Error>
1029where
1030 D: Deserializer<'de>,
1031{
1032 let index: usize = Deserialize::deserialize(deserializer)?;
1033
1034 OS_IPC_CHANNELS_FOR_DESERIALIZATION.with(|os_ipc_channels_for_deserialization| {
1035 Ok(os_ipc_channels_for_deserialization.borrow_mut()[index].to_receiver())
1038 })
1039}