sqlx: Unsupported type _badge of column #6 ("badges") - sql

I'm using Rust's sqlx crate, and trying to perform the following:
query_as!(User, r#"SELECT * FROM users WHERE name ILIKE $1"#, name)
Note that I am using Postgresql.
I am confronted with this error:
error: unsupported type _badge of column #6 ("badges")
--> src\services.rs:16:11
|
16 | match query_as!(User, r#"SELECT * FROM users WHERE name ILIKE $1"#, name)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `query_as` (in Nightly builds, run with -Z macro-backtrace for more info)
Here are my User and Badge definitions:
#[derive(sqlx::Type, Serialize, Deserialize, Display)]
#[sqlx(type_name = "badge")]
pub enum Badge {
Sponsored,
Founder,
Developer,
}
#[derive(Serialize, Deserialize)]
pub struct User {
uuid: Uuid,
date_joined: DateTime<Utc>,
name: String,
badges: Vec<Badge>,
articles: Vec<String>,
followers: i64,
}
My table looks like this:
Column
Type
uuid
uuid
date_joined
timestamp_tz
followers
bigint
badges
badge[]
name
text
articles
text[]
I've even tried to implement the PgHasArrayType trait for the Badge struct:
impl PgHasArrayType for Badge {
fn array_type_info() -> PgTypeInfo {
PgTypeInfo::with_name("_badge")
}
fn array_compatible(ty: &PgTypeInfo) -> bool {
true
}
}
Note: Using the non-macro version of query_as works for some reason.
Any help would be greatly appreciated!

Related

How to correctly describe a golang struct using swagger?

I have some problem. In different sites you can find how to correctly describe go struct using swagger(annotations).
Example:
// swagger:model
type User struct {
// the id for this user
//
// required: true
// min: 1
ID int64 `json:"id"`
// the name for this user
// required: true
// min length: 3
Name string `json:"name"`
}
But can someone help me with, how to describe go struct that is in the method and isn't public?
And what I should to enter in #Param field after description for successful generation docs?
Example:
func (n *newStruct) GetPetInfo(c *gin.Context){
info := struct {
PetId uint64 `form:"petId" json:"petId"`
Sl uint64 `form:"sl" json:"sl"`
}{}
...
}
Help me please with this situation)

How do I define a from method to convert the error in a foreign result type? [duplicate]

This question already has answers here:
Is it possible to implement methods on type aliases?
(1 answer)
Rust proper error handling (auto convert from one error type to another with question mark)
(5 answers)
How to do error handling in Rust and what are the common pitfalls?
(2 answers)
Closed 2 years ago.
I have a pair of Result type aliases, AResult and BResult. AResult is from another crate, and embeds its own error type AError. I have my result (BResult) and I want to convert errors from AError to BError so I can embed them in the BResults that I return.
TIO demo
struct AError(u32);
struct BError(i64);
type AResult = Result<(), AError>;
type BResult = Result<(), BError>;
impl From<AError> for BError {
fn from(item: AError) -> Self {
(item as i64)
}
}
impl From<AResult> for BResult {
fn from(item: AResult) -> Self {
item.map_err(BError::from)
}
}
fn main() {
let result_as_a: AResult = Err(5u32);
let result_as_b = result_as_a;
if let Err(value) = result_as_b {
print!("{}", value);
}
}
I have defined a conversion for the errors from AError to BError (impl From<AError> for BError { ... }) and I'm trying to define a conversion for the Result which uses it, thinking I could do:
impl From<AResult> for BResult {
fn from(item: AResult) -> Self {
item.map_err(BError::from)
}
}
But Rust complains that I can't define things from another crate:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:12:1
|
12 | impl From<AResult> for BResult {
| ^^^^^-------------^^^^^-------
| | | |
| | | `std::result::Result` is not defined in the current crate
| | `std::result::Result` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
I'm trying to define an implementation on BResult, not AResult?!
Am I doing something very stupid? Is there a better way to do this?

Why isn't an error type implicitly converted when I return it?

The following code fails to compile
// winservice.rs
#[macro_use] extern crate err_derive;
extern crate windows_service;
use windows_service::service_manager::{ServiceManager, ServiceManagerAccess};
#[derive(Debug, Error)]
pub enum WinServiceError {
#[error(display = "could not query windows services api")]
WinApiError(windows_service::Error),
}
impl From<windows_service::Error> for WinServiceError {
fn from(error: windows_service::Error) -> Self {
WinServiceError::WinApiError(error)
}
}
fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
ServiceManager::local_computer(None::<&str>, request_access)
}
pub fn main() {
// get_manager();
}
I am getting the error
error[E0308]: mismatched types
--> src/winservice.rs:186:5
|
185 | fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, Error> {
| ----------------------------- expected `std::result::Result<windows_service::service_manager::ServiceManager, winservice::Error>` because of return type
186 | ServiceManager::local_computer(None::<&str>, request_access)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `winservice::Error`, found enum `windows_service::Error`
|
= note: expected type `std::result::Result<_, winservice::Error>`
found type `std::result::Result<_, windows_service::Error>`
Why isn't the Rust compiler auto converting the return type from windows_service::Error to winservice::Error?
Thanks to #Shepmaster's help, I was able resolve the error.
I did not realize that I was returning the result object directly. I had to unwrap the result object for the conversion to work.
The following code attempts to return a value of type Result<_, windows_services::Error> as Result<_, WinServiceError>.
fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
ServiceManager::local_computer(None::<&str>, request_access)
}
But the following code works, because we are now creating a new Result object of the correct signature, and rust compiler performs the conversion between the error types while creating the new object.
fn get_manager(request_access: ServiceManagerAccess) -> Result<ServiceManager, WinServiceError> {
Ok(ServiceManager::local_computer(None::<&str>, request_access)?)
}

fn foo() -> Result<()> throws "expected 2 type arguments"

Why isn't Result<()> allowed when compiling this bit of Rust code? Is it a breaking change between Rust editions?
fn run() -> Result<()> {
let (tx, rx) = channel();
thread::spawn(move || {
do_things_with_tx(&exit_tx);
});
match exit_rx.recv() {
Ok(result) => if let Err(reason) = result {
return Err(reason);
},
Err(e) => {
return Err(e.into());
},
}
Ok(())
}
The compiler says:
error[E0107]: wrong number of type arguments: expected 2, found 1
--> src/main.rs:1000:18
|
1000 | fn run_wifi() -> Result<()> {
| ^^^^^^^^^^ expected 2 type arguments
When I tweak the return type to Result<(), Err>, it says:
error[E0107]: wrong number of type arguments: expected 2, found 0
--> src/main.rs:1000:29
|
1000 | fn run() -> Result<(), Err> {
| ^^^ expected 2 type arguments
This is from the wifi-connect project.
The definition of Result is, and has always been, the following:
pub enum Result<T, E> {
Ok(T),
Err(E),
}
This definition is even presented in the Rust Programming language, to show how simple it is. As a generic sum type of an OK outcome and an error outcome, it always expects two type parameters, and the compiler will complain if it cannot infer them, or the list of type arguments does not have the expected length.
On the other hand, one may find many libraries and respective docs showing a Result with a single type argument, as in Result<()>. What gives?
It's still no magic. By convention, libraries create type aliases for result types at the level of a crate or module. This works pretty well because it is common for those to produce errors of the same, locally created type.
pub type Result<T> = std::result::Result<T, Error>;
Or alternatively, a definition which can still purport as the original result type.
pub type Result<T, E = Error> = std::result::Result<T, E>;
This pattern is so common that some error helper crates such as error-chain, will automatically create a result alias type for each error declared.
As such, if you are using a library that may or may not use error-chain, you are expected to assume that mentions of Result<T> are local type aliases to a domain-specific Result<T, Error>. In case of doubt, clicking on that type in the generated documentation pages will direct you to the concrete definition (in this case, the alias).
From The Rust Programming Language section The ? Operator Can Only Be Used in Functions That Return Result
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let f = File::open("hello.txt")?;
Ok(())
}
TL;DR
use std::io::Result;
Link to the type description
Long answer
I believe that the top-voted answer given by E_net4 the comment flagger is correct. But it doesn't work if applied blindly. In both cases
this
pub type Result<T> = Result<T, Error>;
and this
pub type Result<T, E = Error> = Result<T, E>;
will give the cycle dependency error
error[E0391]: cycle detected when expanding type alias `Result`
--> src\main.rs:149:33
|
149 | pub type Result<T, E = Error> = Result<T, E>;
| ^^^^^^^^^^^^
|
= note: ...which immediately requires expanding type alias `Result` again
= note: type aliases cannot be recursive
= help: consider using a struct, enum, or union instead to break the cycle
= help: see <https://doc.rust-lang.org/reference/types.html#recursive-types> for more information
So as much as users of SO don't want to admit it, but Gabriel soft is very close to elegant solution, because that type alias
pub type Result<T> = result::Result<T, Error>;
is straight from the standard library.
Here it is, our desired Result with 1 generic argument is defined in std::io (docs). To fix the problem I added
use std::io::Result;
fn some_func() -> Result<()> {
...
}
or
use std::io;
fn some_func() -> io::Result<()> {
...
}
rustc 1.62.1
i solved my own error by making a generic Result type to handle the error
As its says it require a generic of T and E, so to simplify things, i had to follow this way
pub type Result = result::Result<T, Error>;

Can I use the "null pointer optimization" for my own non-pointer types?

When you have an Option<&T>, the compiler knows that NULL is never a possible value for &T, and encodes the None variant as NULL instead. This allows for space-saving:
use std::mem;
fn main() {
assert_eq!(mem::size_of::<&u8>(), mem::size_of::<Option<&u8>>());
}
However, if you do the same with a non-pointer type, there's no extra bits to store that value in and extra space is required:
use std::mem;
fn main() {
// fails because left is 1 and right is 2
assert_eq!(mem::size_of::<u8>(), mem::size_of::<Option<u8>>());
}
In general, this is correct. However, I'd like to opt-in to the optimization because I know that my type has certain impossible values. As a made-up-example, I might have a player character that has an age. The age may be unknown, but will never be as high as 255:
struct Age(u8);
struct Player {
age: Option<Age>,
}
I'd like to be able to inform the optimizer of this constraint - Age can never be 255, so it's safe to use that bit pattern as None. Is this possible?
As of Rust 1.28, you can use std::num::NonZeroU8 (and friends). This acts as a wrapper that tells the compiler the contents of a number will never contain a literal zero. It's also why Option<Box<T>> is pointer-sized.
Here's an example showing how to create an Age and read its payload.
use std::num::NonZeroU8;
struct Age(NonZeroU8);
impl Age {
pub fn new(age: u8) -> Age {
let age = NonZeroU8::new(age).expect("Age cannot be zero!");
Age(age)
}
pub fn age(&self) -> u8 {
self.0.get()
}
}
struct Player {
age: Option<Age>,
}
fn main() {
println!("size: {}", std::mem::size_of::<Player>());
// Output: size: 1
}