/* * Copyright 2025 Cade Lueker * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */////// Effect for resolving domain names to IP addresses, and its functions.///pubmod Net.Dns {use IoError.ErrorKinduse IoError.IoErroruse Net.IpAddrimport java.io.IOExceptionimport java.lang.IllegalArgumentExceptionimport java.net.InetAddressimport java.net.UnknownHostException////// Effect for resolving domain names to IP addresses.///pubeffDns {/// Resolves `host` to an IP address.deflookup(host: String): Result[IoError, IpAddr]/// Resolves `host` to all of its IP addresses.deflookupAll(host: String): Result[IoError, List[IpAddr]] }////// Handles the `Dns` effect of the given function `f`.////// In other words, re-interprets the `Dns` effect using the `IO` effect.///pubdefhandle(f: a -> b \ ef): a -> b \ (ef - Dns) + IO = x ->run {f(x) } withhandlerDns {deflookup(host, k) = {try {letaddress = InetAddress.getByName(host);letaddrBytes = Array.toList(address.getAddress());letipAddr = IpAddr.fromBytes(addrBytes);k(Ok(ipAddr)) } catch {caseex: UnknownHostException => k(Err(IoError(ErrorKind.UnknownHost, ex.getMessage())))caseex: IllegalArgumentException => k(Err(IoError(ErrorKind.InvalidInput, ex.getMessage())))caseex: IOException => k(Err(IoError(ErrorKind.Other, ex.getMessage()))) } }deflookupAll(host, k) = {try {letaddrsArr = InetAddress.getAllByName(host);letaddresses = addrsArr |> Array.toList |> List.map(a -> a.getAddress() |> Array.toList) |> List.map(IpAddr.fromBytes);k(Ok(addresses)) } catch {caseex: UnknownHostException => k(Err(IoError(ErrorKind.UnknownHost, ex.getMessage())))caseex: IllegalArgumentException => k(Err(IoError(ErrorKind.InvalidInput, ex.getMessage())))caseex: IOException => k(Err(IoError(ErrorKind.Other, ex.getMessage()))) } } }////// Handles the `Dns` effect of the given function `f`.////// In other words, re-interprets the `Dns` effect using the `IO` effect.///@DefaultHandlerpubdefrunWithIO(f: Unit -> a \ ef): a \ ef - Dns + IO = handle(f)()}