Q:

How to generalize a function over two types with similar fields in different positions? 

I have a function algo which works with a type S1, I also have
a type S2 which contains all of the fields of S1 plus some additional ones. 
How should I modify algo to also accept S2 as input without
creating a temporary variable with type S1 and data from S2? 
struct Moo1 {
    f1: String,
    f2: i32,
}

struct Moo2 {
    f1: String,
    f2: i32,
    other_fields: f32,
}

struct S1 {
    x: i32,
    v: Vec<Moo1>,
}

struct S2 {
    x: i32,
    v: Vec<Moo2>,
}

//before fn algo(s: &S1)
fn algo<??? >(???) { 
    //work with x and v (only with f1 and f2)
}

Where I'm stuck
Let's assume algo has this implementation (my real application has another implementation):
fn algo(s: &S1) {
    println!("s.x: {}", s.x);
    for y in &s.v {
        println!("{} {}",  y.f1, y.f2);
    }
}

To access the field in Moo1 and Moo2 I introduce trait AsMoo, and to access x field and v I introduce trait AsS:
trait AsMoo {
    fn f1(&self) -> &str;
    fn f2(&self) -> i32;
}

trait AsS {
    fn x(&self) -> i32;
    //    fn v(&self) -> ???; 
}

fn algo<S: AsS>(s: &AsS) {
    println!("s.x: {}", s.x());
}

I'm stuck at the implementation of the AsS::v method.  I do not allocate memory to use my algo, but I need a Vec<&AsMoo> in some way. 
Maybe I need to return some kind of Iterator<&AsMoo>, but have no idea how to do it and that looks complex for this problem. 
Maybe I should use macros instead? 

A:

Any problem in computer science can be solved by adding another layer of indirection; at the exception of having too many such layers, of course. 
Therefore, you are correct that you miss a S trait to generalize S1 and S2.  In S, you can use a feature called associated type:
trait Moo {
    fn f1(&self) -> &str;
    fn f2(&self) -> i32;
}

trait S {
    type Mooer: Moo;
    fn x(&self) -> i32;
    fn v(&self) -> &[Self::Mooer];
}

The bit type Mooer: Moo; says: I don't quite know what the exact type Mooer will end up being, but it'll implement the Moo trait. 
This lets you write:
impl S for S1 {
    type Mooer = Moo1;
    fn x(&self) -> i32 { self.x }
    fn v(&self) -> &[Self::Mooer] { &self.v }
}

impl S for S2 {
    type Mooer = Moo2;
    fn x(&self) -> i32 { self.x }
    fn v(&self) -> &[Self::Mooer] { &self.v }
}

fn algo<T: S>(s: &T) {
    println!("s.x: {}", s.x());
    for y in s.v() {
        println!("{} {}",  y.f1(), y.f2());
    }
}

And your generic algo knows that whatever type Mooer ends up being, it conforms to the Moo trait so the interface of Moo is available.