/* Ċ Ġ* ĠCopyright Ġ 2 0 2 1 - 2 0 2 1 Ġthe Ġoriginal Ġauthor Ġor Ġauthors . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttps :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ @ file : Jvm Name (" Cor outines Utils ") Ċ package Ġorg . springframework . cloud . function . context . config Ċ Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . reactive . as Flow Ċ import Ġkotlinx . coroutines . reactor . as Flux Ċ import Ġkotlinx . coroutines . reactor . mono Ċ import Ġreactor . core . publisher . Flux Ċ import Ġjava . lang . reflect . Parameterized Type Ċ import Ġjava . lang . reflect . Type Ċ import Ġjava . lang . reflect . Wildcard Type Ċ import Ġkotlin . coroutines . Continuation Ċ import Ġkotlin . coroutines . intr insics . suspend Coroutine Un intercept ed Or Return Ċ Ċ /** Ċ Ġ* Ġ@ author ĠAd ri en ĠPo up ard Ċ Ġ* Ċ Ġ*/ Ċ Ċ fun ĠisValid Sus pending Function ( kotlin Lambda Target : ĠAny , Ġarg 0 : ĠAny ): ĠBoolean Ġ{ Ċ ĉ return Ġarg 0 Ġis ĠFlux < *> Ġ&& Ġkotlin Lambda Target Ġis ĠFunction 2 < *, Ġ*, Ġ*> Ċ } Ċ Ċ fun Ġget Sus pending Function Arg Type ( type : ĠType ): ĠType Ġ{ Ċ ĉ return Ġget Flow Type Arguments ( type ) Ċ } Ċ Ċ fun Ġget Flow Type Arguments ( type : ĠType ): ĠType Ġ{ Ċ ĉ if (! is Flow Type ( type )) Ġ{ Ċĉ ĉ return Ġtype Ċ ĉ } Ċ ĉ val Ġparameter ized Lower Type Ġ= Ġtype Ġas ĠParameter ized Type ĊĠ ĉ if ( parameter ized Lower Type . actual Type Arguments . isEmpty ()) Ġ{ Ċĉĉ Ġreturn Ġparameter ized Lower Type Ċ ĉ } ĊĊ ĉ val Ġactual Type Argument Ġ= Ġparameter ized Lower Type . actual Type Arguments [ 0 ] Ċ ĉ return Ġif ( actual Type Argument Ġis ĠW ildcard Type ) Ġ{ Ċĉ ĉ val Ġwildcard Type Lower Ġ= Ġparameter ized Lower Type . actual Type Arguments [ 0 ] Ġas ĠW ildcard Type Ċĉ ĉ wildcard Type Lower . upper Bounds [ 0 ] Ċ ĉ } Ġelse Ġ{ Ċĉ ĉ actual Type Argument Ċ ĉ } Ċ } Ċ Ċ fun Ġis Flow Type ( type : ĠType ): ĠBoolean Ġ{ Ċ ĉ return Ġtype . typeName . startsWith ( Flow :: class . qualified Name !! ) Ċ } Ċ Ċ fun Ġget Sus pending Function ReturnType ( type : ĠType ): ĠType Ġ{ Ċ ĉ val Ġlower Ġ= Ġget Continuation Type Arguments ( type ) Ċ ĉ return Ġget Flow Type Arguments ( lower ) Ċ } Ċ Ċ fun Ġis Continuation Type ( type : ĠType ): ĠBoolean Ġ{ Ċ ĉ return Ġtype . typeName . startsWith ( Continuation :: class . qualified Name !! ) Ċ } Ċ Ċ fun Ġis Continuation Unit Type ( type : ĠType ): ĠBoolean Ġ{ Ċ ĉ return Ġis Continuation Type ( type ) Ġ&& Ġtype . typeName . contains ( Unit :: class . qualified Name !! ) Ċ } Ċ Ċ fun Ġis Continuation Flow Type ( type : ĠType ): ĠBoolean Ġ{ Ċ ĉ return Ġis Continuation Type ( type ) Ġ&& Ġtype . typeName . contains ( Flow :: class . qualified Name !! ) Ċ } Ċ Ċ private Ġfun Ġget Continuation Type Arguments ( type : ĠType ): ĠType Ġ{ Ċ ĉ if (! is Continuation Type ( type )) Ġ{ Ċĉ ĉ return Ġtype Ċ ĉ } Ċ ĉ val Ġparameter ized Type Ġ= Ġtype Ġas ĠParameter ized Type Ċ ĉ val Ġwildcard Type Ġ= Ġparameter ized Type . actual Type Arguments [ 0 ] Ġas ĠW ildcard Type Ċ ĉ return Ġwildcard Type . lower Bounds [ 0 ] Ċ } Ċ Ċ fun Ġinvoke Sus pending Function ( kotlin Lambda Target : ĠAny , Ġarg 0 : ĠAny ): ĠFlux < Any > Ġ{ Ċ ĉ val Ġfunction Ġ= Ġkotlin Lambda Target Ġas ĠS uspend Function Ċ ĉ val Ġflux Ġ= Ġarg 0 Ġas ĠFlux < Any > Ċ ĉ return Ġflux Sus pending Flow Function ( flux , Ġfunction ) Ċ } Ċ Ċ fun ĠisValid Sus pending Supplier ( kotlin Lambda Target : ĠAny ): ĠBoolean Ġ{ Ċ ĉ return Ġkotlin Lambda Target Ġis ĠFunction 1 < *, Ġ*> Ċ } Ċ Ċ fun Ġinvoke Sus pending Supplier ( kotlin Lambda Target : ĠAny ): ĠFlux < Any > Ġ{ Ċ ĉ val Ġsupplier Ġ= Ġkotlin Lambda Target Ġas ĠS uspend Supplier Ċ ĉ return Ġmono ( Dispatch ers . Un conf ined ) Ġ{ Ċĉ ĉ suspend Coroutine Un intercept ed Or Return < Flow < Any >> Ġ{ Ċĉĉ ĉ supplier . invoke ( it ) Ċĉ ĉ } Ċ ĉ }. flatMap Many Ġ{ Ċĉ ĉ it . as Flux () Ċ ĉ } Ċ } Ċ Ċ fun Ġflux Sus pending Flow Function ( flux : ĠFlux < Any >, Ġtarget : ĠS uspend Function ): ĠFlux < Any > Ġ{ Ċ ĉ return Ġmono ( Dispatch ers . Un conf ined ) Ġ{ Ċĉ ĉ suspend Coroutine Un intercept ed Or Return < Flow < Any >> Ġ{ Ċĉĉ ĉ target . invoke ( flux . as Flow (), Ġit ) Ċĉ ĉ } Ċ ĉ }. flatMap Many Ġ{ Ċĉ ĉ it . as Flux () Ċ ĉ } Ċ } Ċ Ċ private Ġtype alias ĠS uspend Function Ġ= Ġ( Any ?, ĠAny ?) Ġ-> ĠAny ? Ċ private Ġtype alias ĠS uspend Supplier Ġ= Ġ( Any ?) Ġ-> ĠAny ? Ċ